Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Doiron <ndoiron@mapmeld.com>2011-05-10 19:01:46 (GMT)
committer Nick Doiron <ndoiron@mapmeld.com>2011-05-10 19:01:46 (GMT)
commit5135d08908e319e23fa4d29ea109ffa6a08be7bb (patch)
treee35960df6cff74114f4fb04a5a6a82c2fd85ccaf
SocialCalc-5 includes I/O support for Sugar 0.88+
-rw-r--r--MANIFEST127
-rw-r--r--SocialCalcActivity.py383
-rw-r--r--XOCom.py198
-rw-r--r--activity/activity-socialcalc.svg43
-rw-r--r--activity/activity.info9
-rw-r--r--constants.py88
-rw-r--r--create-dev-env.pl45
-rw-r--r--instance.py39
-rw-r--r--intero.py37
-rw-r--r--interoperability/__init__.py1
-rw-r--r--interoperability/__init__.pyobin0 -> 165 bytes
-rw-r--r--interoperability/lotus_wk4.py291
-rw-r--r--interoperability/lotus_wk4.pyobin0 -> 4727 bytes
-rw-r--r--interoperability/xls/__init__.py1
-rw-r--r--interoperability/xls/__init__.pyobin0 -> 169 bytes
-rw-r--r--interoperability/xls/compound.py127
-rw-r--r--interoperability/xls/compound.pyobin0 -> 3718 bytes
-rw-r--r--interoperability/xls/convert_to_scalcstring.py372
-rw-r--r--interoperability/xls/convert_to_scalcstring.pyobin0 -> 7959 bytes
-rw-r--r--interoperability/xls/function.py246
-rw-r--r--interoperability/xls/function.pyobin0 -> 8142 bytes
-rw-r--r--interoperability/xls/function.txt249
-rw-r--r--interoperability/xls/workbook.py432
-rw-r--r--interoperability/xls/workbook.pyobin0 -> 14566 bytes
-rw-r--r--locale/af/LC_MESSAGES/com.socialtext.SocialCalcActivity.mobin0 -> 39303 bytes
-rw-r--r--locale/ar/LC_MESSAGES/com.socialtext.SocialCalcActivity.mobin0 -> 45671 bytes
-rw-r--r--locale/de/LC_MESSAGES/com.socialtext.SocialCalcActivity.mobin0 -> 39241 bytes
-rw-r--r--locale/es/LC_MESSAGES/com.socialtext.SocialCalcActivity.mobin0 -> 40015 bytes
-rw-r--r--locale/es/activity.linfo2
-rw-r--r--locale/fr/LC_MESSAGES/com.socialtext.SocialCalcActivity.mobin0 -> 40302 bytes
-rw-r--r--locale/hi/LC_MESSAGES/com.socialtext.SocialCalcActivity.mobin0 -> 57963 bytes
-rw-r--r--locale/hi/activity.linfo2
-rw-r--r--locale/ja/LC_MESSAGES/com.socialtext.SocialCalcActivity.mobin0 -> 42442 bytes
-rw-r--r--locale/pt/LC_MESSAGES/com.socialtext.SocialCalcActivity.mobin0 -> 39279 bytes
-rw-r--r--locale/ru/LC_MESSAGES/com.socialtext.SocialCalcActivity.mobin0 -> 51457 bytes
-rw-r--r--locale/zh_CN/LC_MESSAGES/com.socialtext.SocialCalcActivity.mobin0 -> 35419 bytes
-rw-r--r--localized_strings_file.py402
-rw-r--r--logic.py364
-rw-r--r--news59
-rw-r--r--po/af.po1476
-rw-r--r--po/ar.po1478
-rw-r--r--po/de.po1459
-rw-r--r--po/es.po1475
-rw-r--r--po/fr.po1479
-rw-r--r--po/hi.po1480
-rw-r--r--po/ja.po1473
-rw-r--r--po/pt.po1477
-rw-r--r--po/ru.po1474
-rw-r--r--po/zh_CN.po1464
-rw-r--r--result.py25
-rw-r--r--server.py69
-rw-r--r--setup.py18
-rw-r--r--test-web-view.py45
-rw-r--r--todo6
-rw-r--r--web/formatnumber2.js950
-rw-r--r--web/formula1.js4754
-rw-r--r--web/images/sc-1x1.gifbin0 -> 42 bytes
-rw-r--r--web/images/sc-aligncenter.gifbin0 -> 70 bytes
-rw-r--r--web/images/sc-alignleft.gifbin0 -> 70 bytes
-rw-r--r--web/images/sc-alignright.gifbin0 -> 71 bytes
-rw-r--r--web/images/sc-bordersoff.gifbin0 -> 70 bytes
-rw-r--r--web/images/sc-borderson.gifbin0 -> 89 bytes
-rw-r--r--web/images/sc-chooserarrow.gifbin0 -> 150 bytes
-rw-r--r--web/images/sc-commentbg.gifbin0 -> 54 bytes
-rw-r--r--web/images/sc-copy.gifbin0 -> 97 bytes
-rw-r--r--web/images/sc-cursorinsertleft.gifbin0 -> 46 bytes
-rw-r--r--web/images/sc-cursorinsertup.gifbin0 -> 46 bytes
-rw-r--r--web/images/sc-cut.gifbin0 -> 87 bytes
-rw-r--r--web/images/sc-defaultcolor.gifbin0 -> 46 bytes
-rw-r--r--web/images/sc-delete.gifbin0 -> 84 bytes
-rw-r--r--web/images/sc-deletecol.gifbin0 -> 95 bytes
-rw-r--r--web/images/sc-deleterow.gifbin0 -> 88 bytes
-rw-r--r--web/images/sc-divider1.gifbin0 -> 45 bytes
-rw-r--r--web/images/sc-endcap-h.gifbin0 -> 874 bytes
-rw-r--r--web/images/sc-endcap-v.gifbin0 -> 869 bytes
-rw-r--r--web/images/sc-filldown.gifbin0 -> 105 bytes
-rw-r--r--web/images/sc-fillright.gifbin0 -> 100 bytes
-rw-r--r--web/images/sc-formuladialog.gifbin0 -> 76 bytes
-rw-r--r--web/images/sc-insertcol.gifbin0 -> 100 bytes
-rw-r--r--web/images/sc-insertrow.gifbin0 -> 86 bytes
-rw-r--r--web/images/sc-less-hd.gifbin0 -> 935 bytes
-rw-r--r--web/images/sc-less-hh.gifbin0 -> 145 bytes
-rw-r--r--web/images/sc-less-hn.gifbin0 -> 932 bytes
-rw-r--r--web/images/sc-less-vd.gifbin0 -> 936 bytes
-rw-r--r--web/images/sc-less-vh.gifbin0 -> 158 bytes
-rw-r--r--web/images/sc-less-vn.gifbin0 -> 944 bytes
-rw-r--r--web/images/sc-linkdialog.gifbin0 -> 71 bytes
-rw-r--r--web/images/sc-linkout.gifbin0 -> 275 bytes
-rw-r--r--web/images/sc-logo.gifbin0 -> 423 bytes
-rw-r--r--web/images/sc-main-h.gifbin0 -> 837 bytes
-rw-r--r--web/images/sc-main-v.gifbin0 -> 847 bytes
-rw-r--r--web/images/sc-merge.gifbin0 -> 90 bytes
-rw-r--r--web/images/sc-more-hd.gifbin0 -> 937 bytes
-rw-r--r--web/images/sc-more-hh.gifbin0 -> 928 bytes
-rw-r--r--web/images/sc-more-hn.gifbin0 -> 932 bytes
-rw-r--r--web/images/sc-more-vd.gifbin0 -> 943 bytes
-rw-r--r--web/images/sc-more-vh.gifbin0 -> 159 bytes
-rw-r--r--web/images/sc-more-vn.gifbin0 -> 938 bytes
-rw-r--r--web/images/sc-movefrom.gifbin0 -> 100 bytes
-rw-r--r--web/images/sc-movefromoff.gifbin0 -> 89 bytes
-rw-r--r--web/images/sc-moveinsert.gifbin0 -> 97 bytes
-rw-r--r--web/images/sc-moveinsertoff.gifbin0 -> 92 bytes
-rw-r--r--web/images/sc-movepaste.gifbin0 -> 95 bytes
-rw-r--r--web/images/sc-movepasteoff.gifbin0 -> 90 bytes
-rw-r--r--web/images/sc-multilinedialog.gifbin0 -> 63 bytes
-rw-r--r--web/images/sc-paneslider-h.gifbin0 -> 897 bytes
-rw-r--r--web/images/sc-paneslider-v.gifbin0 -> 884 bytes
-rw-r--r--web/images/sc-paste.gifbin0 -> 100 bytes
-rw-r--r--web/images/sc-pasteformats.gifbin0 -> 99 bytes
-rw-r--r--web/images/sc-range2.gifbin0 -> 46 bytes
-rw-r--r--web/images/sc-recalc.gifbin0 -> 190 bytes
-rw-r--r--web/images/sc-redo.gifbin0 -> 89 bytes
-rw-r--r--web/images/sc-scrollarea-h.gifbin0 -> 858 bytes
-rw-r--r--web/images/sc-scrollarea-v.gifbin0 -> 875 bytes
-rw-r--r--web/images/sc-sumdialog.gifbin0 -> 69 bytes
-rw-r--r--web/images/sc-swapcolors.gifbin0 -> 96 bytes
-rw-r--r--web/images/sc-thumb-hd.gifbin0 -> 896 bytes
-rw-r--r--web/images/sc-thumb-hh.gifbin0 -> 884 bytes
-rw-r--r--web/images/sc-thumb-hn.gifbin0 -> 939 bytes
-rw-r--r--web/images/sc-thumb-vd.gifbin0 -> 884 bytes
-rw-r--r--web/images/sc-thumb-vh.gifbin0 -> 881 bytes
-rw-r--r--web/images/sc-thumb-vn.gifbin0 -> 937 bytes
-rw-r--r--web/images/sc-trackingline-h.gifbin0 -> 54 bytes
-rw-r--r--web/images/sc-trackingline-v.gifbin0 -> 54 bytes
-rw-r--r--web/images/sc-undo.gifbin0 -> 90 bytes
-rw-r--r--web/images/sc-unmerge.gifbin0 -> 93 bytes
-rw-r--r--web/images/sc-wikiflag.gifbin0 -> 81 bytes
-rw-r--r--web/images/sc-wikilinkflag.gifbin0 -> 88 bytes
-rw-r--r--web/index.html1760
-rw-r--r--web/jquery.js3408
-rw-r--r--web/legal.txt72
-rw-r--r--web/license.txt705
-rw-r--r--web/socialcalc-3.js5697
-rw-r--r--web/socialcalcconstants.js792
-rw-r--r--web/socialcalcpopup.js1618
-rw-r--r--web/socialcalcspreadsheetcontrol.js3551
-rw-r--r--web/socialcalctableeditor.js5127
-rw-r--r--web/xocom.js3595
138 files changed, 50444 insertions, 0 deletions
diff --git a/MANIFEST b/MANIFEST
new file mode 100644
index 0000000..3e535ea
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,127 @@
+web/legal.txt
+web/jquery.js
+web/socialcalctableeditor.js
+web/formula1.js
+web/urlJump.html
+web/index.html
+web/socialcalcspreadsheetcontrol.js
+web/images/sc-chooserarrow.gif
+web/images/sc-sumdialog.gif
+web/images/sc-endcap-h.gif
+web/images/sc-deletecol.gif
+web/images/sc-endcap-v.gif
+web/images/sc-more-vd.gif
+web/images/sc-more-vh.gif
+web/images/sc-more-vn.gif
+web/images/sc-cut.gif
+web/images/sc-filldown.gif
+web/images/sc-cursorinsertup.gif
+web/images/sc-divider1.gif
+web/images/sc-deleterow.gif
+web/images/sc-aligncenter.gif
+web/images/sc-bordersoff.gif
+web/images/sc-delete.gif
+web/images/sc-unmerge.gif
+web/images/sc-movepasteoff.gif
+web/images/sc-paneslider-h.gif
+web/images/sc-paneslider-v.gif
+web/images/sc-formuladialog.gif
+web/images/sc-commentbg.gif
+web/images/sc-linkout.gif
+web/images/sc-cursorinsertleft.gif
+web/images/sc-alignright.gif
+web/images/sc-1x1.gif
+web/images/sc-paste.gif
+web/images/sc-recalc.gif
+web/images/sc-range2.gif
+web/images/sc-linkdialog.gif
+web/images/sc-main-h.gif
+web/images/sc-main-v.gif
+web/images/sc-wikiflag.gif
+web/images/sc-pasteformats.gif
+web/images/sc-wikilinkflag.gif
+web/images/sc-moveinsert.gif
+web/images/sc-copy.gif
+web/images/sc-merge.gif
+web/images/sc-alignleft.gif
+web/images/sc-insertcol.gif
+web/images/sc-moveinsertoff.gif
+web/images/sc-borderson.gif
+web/images/sc-trackingline-h.gif
+web/images/sc-trackingline-v.gif
+web/images/sc-defaultcolor.gif
+web/images/sc-thumb-hd.gif
+web/images/sc-thumb-hh.gif
+web/images/sc-thumb-hn.gif
+web/images/sc-movepaste.gif
+web/images/sc-logo.gif
+web/images/sc-insertrow.gif
+web/images/sc-fillright.gif
+web/images/sc-movefrom.gif
+web/images/sc-thumb-vd.gif
+web/images/sc-thumb-vh.gif
+web/images/sc-thumb-vn.gif
+web/images/sc-multilinedialog.gif
+web/images/sc-movefromoff.gif
+web/images/sc-redo.gif
+web/images/sc-swapcolors.gif
+web/images/sc-undo.gif
+web/images/sc-less-hd.gif
+web/images/sc-less-hh.gif
+web/images/sc-less-hn.gif
+web/images/sc-scrollarea-h.gif
+web/images/sc-scrollarea-v.gif
+web/images/sc-less-vd.gif
+web/images/sc-less-vh.gif
+web/images/sc-less-vn.gif
+web/images/sc-more-hd.gif
+web/images/sc-more-hh.gif
+web/images/sc-more-hn.gif
+web/socialcalcconstants.js
+web/license.txt
+web/formatnumber2.js
+web/socialcalc-3.js
+web/socialcalcpopup.js
+web/xocom.js
+todo
+news
+manifest
+create-dev-env.pl
+setup.py
+test-web-view.py
+SocialCalcActivity.py
+interoperability/__init__.py
+interoperability/lotus_wk4.py
+interoperability/xls/__init__.py
+interoperability/xls/convert_to_scalcstring.py
+interoperability/xls/workbook.py
+interoperability/xls/compound.py
+interoperability/xls/function.py
+interoperability/xls/function.txt
+po/af.po
+po/ar.po
+po/de.po
+po/fr.po
+po/ja.po
+po/pt.po
+po/ru.po
+po/zh_CN.po
+po/hi.po
+po/es.po
+locale/hi/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
+locale/hi/activity.linfo
+locale/es/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
+locale/es/activity.linfo
+locale/af/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
+locale/ar/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
+locale/fr/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
+locale/ja/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
+locale/de/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
+locale/pt/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
+locale/ru/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
+locale/zh_CN/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
+localized_strings_file.py
+XOCom.py
+intero.py
+activity/activity.info
+activity/activity-socialcalc.svg
diff --git a/SocialCalcActivity.py b/SocialCalcActivity.py
new file mode 100644
index 0000000..1941298
--- /dev/null
+++ b/SocialCalcActivity.py
@@ -0,0 +1,383 @@
+from sugar.activity import activity
+from sugar import env
+import os
+import gtk
+import gobject
+import hulahop
+hulahop.startup(os.path.join(env.get_profile_path(), 'gecko'))
+from XOCom import XOCom
+import sys
+import logging
+import telepathy
+from dbus.service import method, signal
+from dbus.gobject_service import ExportedGObject
+from sugar.presence import presenceservice
+from sugar.presence.tubeconn import TubeConnection
+
+
+import intero
+
+SERVICE = "com.socialtext.SocialCalcActivity"
+IFACE = SERVICE
+PATH = "/com/socialtext/SocialCalcActivity"
+#global_filename=''
+global_content=''
+flag_WriteFromWriteFile=True
+flag_toActivateSetInterval=True
+
+class SocialCalcActivity (activity.Activity):
+ def __init__(self, handle):
+ activity.Activity.__init__(self, handle)
+ self.set_title('SocialCalc')
+ self._logger = logging.getLogger('OnePageWiki-Activity')
+
+ # The XOCom object helps us communicate with the browser
+ # This uses web/index.html as the default page to load
+ self.xocom = XOCom(self.control_sending_text) #REMEMBER THAT I HAVE STILL TO SEND THE ARGUMENT IN THE XOCOM CLASS
+
+ toolbox = activity.ActivityToolbox(self)
+ self.set_toolbox(toolbox)
+ toolbox.show()
+ ##self.xocom.send_to_browser_localize(['initlocalize'])
+
+ self.set_canvas( self.xocom.create_webview() )
+
+ self.hellotube = None # Shared session #REQUIRED
+ self.initiating = False
+
+ self.pservice = presenceservice.get_instance()
+
+ owner = self.pservice.get_owner()
+ self.owner = owner
+
+ self.connect('shared', self._shared_cb)
+ self.connect('joined', self._joined_cb)
+
+ self.filename='' #ADDED SPECIFICALLY TO CALL WRITE AND READ METHODS
+ self.content=''
+
+ #calling to initialize strings in localization
+ #should wait for init complete from browser
+ gobject.timeout_add(4000, self.xocom.send_to_browser_localize,['initlocalize'])
+
+
+ def _shared_cb(self, activity):
+ self._logger.debug('My activity was shared')
+ print 'my activity is shared'
+ self.initiating = True
+ self._sharing_setup()
+
+ self._logger.debug('This is my activity: making a tube...')
+ print 'This is my activity: making a tube...'
+ id = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferDBusTube(
+ SERVICE, {})
+
+ def _sharing_setup(self):
+ if self._shared_activity is None:
+ self._logger.error('Failed to share or join activity')
+ print 'Failed to share or join activity'
+ return
+
+ self.conn = self._shared_activity.telepathy_conn
+ self.tubes_chan = self._shared_activity.telepathy_tubes_chan
+ self.text_chan = self._shared_activity.telepathy_text_chan
+
+ self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal(
+ 'NewTube', self._new_tube_cb)
+
+ self._shared_activity.connect('buddy-joined', self._buddy_joined_cb)
+ self._shared_activity.connect('buddy-left', self._buddy_left_cb)
+
+ #self.entry.set_sensitive(True)
+ #self.entry.grab_focus()
+
+ # Optional - included for example:
+ # Find out who's already in the shared activity:
+ #for buddy in self._shared_activity.get_joined_buddies():
+ #self._logger.debug('Buddy %s is already in the activity',
+ #buddy.props.nick)
+
+ def _list_tubes_reply_cb(self, tubes):
+ for tube_info in tubes:
+ self._new_tube_cb(*tube_info)
+
+ def _list_tubes_error_cb(self, e):
+ self._logger.error('ListTubes() failed: %s', e)
+
+
+ def _joined_cb(self, activity):
+ if not self._shared_activity:
+ return
+
+ self._logger.debug('Joined an existing shared activity')
+ print 'Joined an existing shared activity'
+ self.initiating = False
+ self._sharing_setup()
+
+ self._logger.debug('This is not my activity: waiting for a tube...')
+ print 'This is not my activity: waiting for a tube...'
+ self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes(
+ reply_handler=self._list_tubes_reply_cb,
+ error_handler=self._list_tubes_error_cb)
+
+ def _new_tube_cb(self, id, initiator, type, service, params, state):
+ self._logger.debug('New tube: ID=%d initator=%d type=%d service=%s '
+ 'params=%r state=%d', id, initiator, type, service,
+ params, state)
+ if (type == telepathy.TUBE_TYPE_DBUS and
+ service == SERVICE):
+ if state == telepathy.TUBE_STATE_LOCAL_PENDING:
+ self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].AcceptDBusTube(id)
+ tube_conn = TubeConnection(self.conn,
+ self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES],
+ id, group_iface=self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP])
+ self.hellotube = TextSync(tube_conn, self.initiating,
+ self._get_buddy,self.read_shared,self.write_shared,self.xocom)
+
+ def _buddy_joined_cb (self, activity, buddy):
+ """Called when a buddy joins the shared activity.
+
+ This doesn't do much here as HelloMesh doesn't have much
+ functionality. It's up to you do do interesting things
+ with the Buddy...
+ """
+ self._logger.debug('Buddy %s joined', buddy.props.nick)
+ print 'Buddy %s joined' % (buddy.props.nick)
+
+ def _buddy_left_cb (self, activity, buddy):
+ """Called when a buddy leaves the shared activity.
+
+ This doesn't do much here as HelloMesh doesn't have much
+ functionality. It's up to you do do interesting things
+ with the Buddy...
+ """
+ self._logger.debug('Buddy %s left', buddy.props.nick)
+ print 'Buddy %s left' % (buddy.props.nick)
+
+ def _get_buddy(self, cs_handle):
+ """Get a Buddy from a channel specific handle."""
+ self._logger.debug('Trying to find owner of handle %u...', cs_handle)
+ group = self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP]
+ my_csh = group.GetSelfHandle()
+ self._logger.debug('My handle in that group is %u', my_csh)
+ if my_csh == cs_handle:
+ handle = self.conn.GetSelfHandle()
+ self._logger.debug('CS handle %u belongs to me, %u', cs_handle, handle)
+ elif group.GetGroupFlags() & telepathy.CHANNEL_GROUP_FLAG_CHANNEL_SPECIFIC_HANDLES:
+ handle = group.GetHandleOwners([cs_handle])[0]
+ self._logger.debug('CS handle %u belongs to %u', cs_handle, handle)
+ else:
+ handle = cs_handle
+ self._logger.debug('non-CS handle %u belongs to itself', handle)
+ # XXX: deal with failure to get the handle owner
+ assert handle != 0
+ return self.pservice.get_buddy_by_telepathy_handle(
+ self.conn.service_name, self.conn.object_path, handle)
+
+ def write_file(self, filename):
+
+## print 'in write file'
+## print content
+## print 'filename is ',filename,' mime ',self.metadata['mime_type']
+ self.metadata['mime_type']='application/scalc' ## The mime_type is changed beacause the name of file still remains .wk* even when it is saved and
+ ## opened in scalc format. So, to distinguish it from original one because, the mime_type of a binary
+ ## .wk* file would be application/vnd.lotus-1-2-3
+
+ ##self.xocom.send_to_browser_localize(['initlocalize'])
+ content = self.xocom.send_to_browser('write')
+ if content:
+ fh = open(filename, 'w')
+ fh.write(content)
+ fh.close()
+
+ if not self.hellotube==None:
+ if flag_WriteFromWriteFile:
+ #self.control_sending_text() COMMENTED ONLY FOR THIS TIME WHILE CHECKING UNCOMMENT IT OVER THE TIME
+ self.hellotube.SendText(['whole',content]) #COMMENT THIS LINE AT THAT TIME
+
+
+ def read_file(self, filename):
+ #print '\nin read file\n'
+ file_extension_value=intero.check_file_extension(filename)
+ print ' \nthe extension is ',file_extension_value[1],' and the value is ',file_extension_value[0],'\n'
+
+ if file_extension_value[0] and (self.metadata['mime_type']!='application/scalc') :
+ fh = open(filename, 'rb')
+ #print 'filename is ',filename,' mime ',self.metadata['mime_type']
+ #print self.metadata['mime_type']
+ content = fh.read()
+ fh.close()
+ #print content
+ content=intero.convert(content,file_extension_value[1])
+
+ else:
+ fh = open(filename, 'r')
+ content = fh.read()
+ fh.close()
+
+ #print content
+ #return
+ def send_delayed_read():
+ self.xocom.send_to_browser('read', content)
+ return False
+ # We must delay this to give the browser time to start up
+ # It would be better if this send_to_browser was instead triggered
+ # once the browser had finished loading.
+ gobject.timeout_add(5000, send_delayed_read)
+
+
+ def write_shared(self):
+ content=self.xocom.send_to_browser('write')
+ global_content=content
+ self.content=content
+ return content
+ #self.hellotube.SendText(self.content)
+
+ def read_shared(self,content):
+ self.xocom.send_to_browser('read',content)
+
+ def control_sending_text(self,array='', topic='', str=''):
+ if not str=='': #just to check that the string is received from the js part
+ print 'reached control_sending_text from js part ',str
+ #content=self.write_shared()
+ #content=array
+
+ if str=='execute':
+ print 'in execute in control_sending_text'
+ global_content=array[1]
+ self.content=global_content
+ self.hellotube.SendText(array)
+
+
+class TextSync(ExportedGObject):
+ """The bit that talks over the TUBES!!!"""
+
+ def __init__(self, tube, is_initiator, get_buddy,read_shared,write_shared,xocom):
+ super(TextSync, self).__init__(tube, PATH)
+ self._logger = logging.getLogger('OnePageWiki-Activity.Textsync')
+ self.tube = tube
+ self.is_initiator = is_initiator
+ #self.text_received_cb = text_received_cb
+ #self._alert = alert
+ self.entered = False # Have we set up the tube?
+ self.text = '' # State that gets sent or received #to check whether anything is received till now or not
+ self._get_buddy = get_buddy # Converts handle to Buddy object
+ self.tube.watch_participants(self.participant_change_cb)
+ self.read_shared=read_shared
+ self.write_shared=write_shared
+ self.xocom=xocom
+
+
+ def participant_change_cb(self, added, removed):
+ self._logger.debug('Tube: Added participants: %r', added)
+ self._logger.debug('Tube: Removed participants: %r', removed)
+ for handle, bus_name in added:
+ buddy = self._get_buddy(handle)
+ if buddy is not None:
+ self._logger.debug('Tube: Handle %u (Buddy %s) was added',
+ handle, buddy.props.nick)
+ print 'Buddy %s was added' % (buddy.props.nick)
+ for handle in removed:
+ buddy = self._get_buddy(handle)
+ if buddy is not None:
+ self._logger.debug('Buddy %s was removed' % buddy.props.nick)
+ print 'Buddy %s was added' % (buddy.props.nick)
+ if not self.entered:
+ if self.is_initiator:
+ self._logger.debug("I'm initiating the tube, will "
+ "watch for hellos.")
+ print 'I am initiating the tube'
+ self.add_hello_handler()
+ else:
+ self._logger.debug('Hello, everyone! What did I miss?')
+ print 'what did I miss'
+ self.Hello()
+ self.entered = True
+
+ @signal(dbus_interface=IFACE, signature='')
+ def Hello(self):
+ """Say Hello to whoever else is in the tube."""
+ self._logger.debug('I said Hello.')
+ print 'I said Hello.'
+
+ @method(dbus_interface=IFACE, in_signature='s', out_signature='')
+ def World(self, text):
+ """To be called on the incoming XO after they Hello."""
+ if not self.text:
+ self._logger.debug('Somebody called World and sent me %s',
+ text)
+ print 'Somebody called World and sent me %s' %(text)
+
+ self.text = text
+ self.read_shared(content=text)
+ # now I can World others
+ self.add_hello_handler()
+ else:
+ self._logger.debug("I've already been welcomed, doing nothing")
+ print 'I have already been welcomed'
+
+ def add_hello_handler(self):
+ self._logger.debug('Adding hello handler.')
+ print 'in add_hello_handler'
+ self.tube.add_signal_receiver(self.hello_cb, 'Hello', IFACE,
+ path=PATH, sender_keyword='sender')
+ self.tube.add_signal_receiver(self.sendtext_cb, 'SendText', IFACE,
+ path=PATH, sender_keyword='sender')
+ global flag_toActivateSetInterval
+ if flag_toActivateSetInterval: #NOTE THAT THIS PART NEEDS TO BE UNCOMMENTED TO ACTUALLY IMPLEMENT WHAT WE WANT TO IN EXECUTECOMMAND
+ print 'start: sending check'
+ self.xocom.send_to_browser('check')
+ #flag_toActivateSetInterval=False
+ print 'exit: sending check'
+
+
+
+ def hello_cb(self, sender=None):
+ """Somebody Helloed me. World them."""
+ if sender == self.tube.get_unique_name():
+ # sender is my bus name, so ignore my own signal
+ return
+ self._logger.debug('Newcomer %s has joined', sender)
+ print 'Newcomer %s has joined' % (sender)
+ self._logger.debug('Welcoming newcomer and sending them the game state')
+ print 'Welcoming newcomer and sending them the game state'
+ content=self.write_shared()
+ self.tube.get_object(sender, PATH).World(content,
+ dbus_interface=IFACE)
+
+ #global flag_toActivateSetInterval
+ #if flag_toActivateSetInterval:
+ #print 'start: sending check'
+ #self.xocom.send_to_browser('check')
+ ##flag_toActivateSetInterval=False
+ #print 'exit: sending check'
+
+ def sendtext_cb(self, text, sender=None):
+ """Handler for somebody sending SendText"""
+ if sender == self.tube.get_unique_name():
+ # sender is my bus name, so ignore my own signal
+ return
+
+ if text[0]=='execute':
+ self._logger.debug('%s sent text %s', sender, text[1])
+ print 'received text', text[1]
+ self.text = text[1]
+ self.xocom.send_to_browser_shared(text)
+
+
+ @signal(dbus_interface=IFACE, signature='as')
+ def SendText(self, text):
+ """Send some text to all participants."""
+ #self.text = text
+ #self._logger.debug('Sent text: %s', text)
+ if text[0]=='whole':
+ print 'in whole: sending sendtext signal',text[1]
+
+ elif text[0]=='execute':
+ print 'in execute: sending sendtext signal',text[1]
+
+ #print 'sending sendtext signal'
+ #self._alert('SendText', 'Sent %s' % text)
+
+
+
diff --git a/XOCom.py b/XOCom.py
new file mode 100644
index 0000000..e4cfa4c
--- /dev/null
+++ b/XOCom.py
@@ -0,0 +1,198 @@
+import threading
+from threading import *
+from logic import ServerLogic
+from server import Server
+from instance import Instance
+from sugar.activity.activity import get_bundle_path
+from hulahop.webview import WebView
+from xpcom import components
+from localized_strings_file import localized_strings
+
+class XOCom:
+ # Constructor gives full XPCom access by default
+ # This should be improved for future apps that may not need/want full access
+ cometPort = 8889
+ ajaxPort = 8890
+
+ def __init__(self, control_sending_text,uri=None):
+ self.cond = Condition()
+ #h = hash(Instance.instanceId)
+ self.__class__.cometPort = 10
+ self.__class__.ajaxPort = 11
+ self.cometLogic = ServerLogic(self)
+ #self.ajaxServer = ServerThread(self.__class__.ajaxPort, self.cometLogic)
+ #self.ajaxServer.start()
+ #self.cometServer = ServerThread(self.__class__.cometPort, self.cometLogic)
+ #self.cometServer.start()
+ if uri:
+ self.uri = uri
+ else:
+ self.uri = 'file://' + get_bundle_path() + '/web/index.html?ajax='+str(self.__class__.ajaxPort)+'&comet='+str(self.__class__.cometPort);
+ self.control_sending_text=control_sending_text
+ self.give_full_xpcom_access()
+ self.set_observer()
+ ##self.send_to_browser_localize(['initlocalize']) ## to initialize the localized strings in socialcalc
+
+ # Give the browser permission to use XPCom interfaces
+ # This is necessary for XPCom communication to work
+ # Note: Not all of these preferences may be required - requires further
+ # investigation
+ def give_full_xpcom_access(self):
+ pref_class = components.classes["@mozilla.org/preferences-service;1"]
+ prefs = pref_class.getService(components.interfaces.nsIPrefService)
+ prefs.getBranch('signed.applets.').setBoolPref('codebase_principal_support',
+ True);
+ prefs.getBranch('capability.principal.').setCharPref(
+ 'socialcalc.granted', 'UniversalXPConnect')
+ prefs.getBranch('capability.principal.').setCharPref(
+ 'socialcalc.id', self.uri)
+
+ # Wrapper method to create a new webview embedded browser component
+ # Uses hulahop's WebView. Assumes that you'll want to serve
+ # web/index.html relative to your activity directory.
+ def create_webview(self):
+ self.web_view = WebView()
+ ##self.uri = 'file://' + get_bundle_path() + '/web/index.html';
+ self.web_view.load_uri(self.uri)
+ self.web_view.show()
+ return self.web_view
+
+ def set_observer(self):
+ #try:
+ print 'enter: set_observer'
+ observerService = components.classes["@mozilla.org/observer-service;1"]
+ ob_serv = observerService.getService(components.interfaces.nsIObserverService);
+ observer=Observer(self.control_sending_text)
+ ob_serv.addObserver(observer,"xo-message2",False);
+ print 'exit: set_observer'
+ #except:
+ #print 'error is there, remove try and except thing'
+
+
+ # Use XPCom to execute a javascript callback registered with XO.js
+ # The command will execute a javascript method registered with the same name,
+ # and return any value received from the javascript
+ def send_to_browser(self, command, parameter=None):
+ if((command == "read") and (parameter is not None)):
+ self.web_view.load_uri("javascript:XO.observer.setSheet('"+parameter.replace('\\n','DECNEWLINE').replace('\n','NEWLINE').replace("'","\\'")+"');void(0);")
+ return
+
+ # Set up an array for parameters and return values for the XPCom call
+ array = components.classes["@mozilla.org/array;1"].createInstance(
+ components.interfaces.nsIMutableArray)
+
+ # Optionally pass data to the javascript
+ if parameter:
+ str = components.classes["@mozilla.org/supports-string;1"].createInstance(
+ components.interfaces.nsISupportsString)
+ str.data = parameter
+ array.appendElement(str, False)
+
+ # Use XPCom to send an event to a javascript observer (web/xo.js)
+ observerService = components.classes["@mozilla.org/observer-service;1"]
+ ob_serv = observerService.getService(components.interfaces.nsIObserverService)
+ ob_serv.notifyObservers(array, "xo-message", command)
+ #ob_serv.addObserver(self.control_sending_text,"xo-message2",False)
+
+ # check if the browser returned anything
+ if array.length:
+ iter = array.enumerate()
+ result = iter.getNext()
+ result = result.QueryInterface(components.interfaces.nsISupportsString)
+ return result.toString()
+ return None
+
+ def send_to_browser_shared(self,command):
+ if command[0]=='execute':
+ array = components.classes["@mozilla.org/array;1"].createInstance(components.interfaces.nsIMutableArray)
+ str = components.classes["@mozilla.org/supports-string;1"].createInstance(components.interfaces.nsISupportsString)
+ str.data = command[1]
+ array.appendElement(str, False)
+ str2 = components.classes["@mozilla.org/supports-string;1"].createInstance(components.interfaces.nsISupportsString)
+ str2.data = command[2]
+ array.appendElement(str2, False)
+
+ observerService = components.classes["@mozilla.org/observer-service;1"]
+ ob_serv = observerService.getService(components.interfaces.nsIObserverService);
+ if not array.length:
+ print 'no need of sending anywhere , array is empty'
+ ob_serv.notifyObservers(array, "xo-message", 'execute');
+
+ def send_to_browser_localize(self,command):
+ #self.ajaxServer.closing = 1
+ print 'sending to javascript part to localize\n'
+ #array = components.classes["@mozilla.org/array;1"].createInstance(components.interfaces.nsIMutableArray)
+ localstr = "javascript:XO.lang=["
+ for i,j in localized_strings.iteritems():
+ localstr = localstr+"'"+i.replace("'","\\'")+"','"+j.replace("'","\\'")+"',"
+ #str1 = components.classes["@mozilla.org/supports-string;1"].createInstance(components.interfaces.nsISupportsString)
+ #str1.data=i
+ #array.appendElement(str1, False)
+ #str2 = components.classes["@mozilla.org/supports-string;1"].createInstance(components.interfaces.nsISupportsString)
+ #str2.data=j
+ #array.appendElement(str2, False)
+ localstr = localstr+"'xv'];XO.observe();void(0);"
+ self.web_view.load_uri(localstr)
+ return
+
+ observerService = components.classes["@mozilla.org/observer-service;1"]
+ ob_serv = observerService.getService(components.interfaces.nsIObserverService);
+ if not array.length:
+ print 'no need of sending anywhere , array is empty'
+ ob_serv.notifyObservers(array, "xo-message3", 'initlocalize');
+
+ if array.length:
+ iter = array.enumerate()
+ result = iter.getNext()
+ result = result.QueryInterface(components.interfaces.nsISupportsString)
+ print result.toString()
+
+
+class Observer():
+ _com_interfaces_ = components.interfaces.nsIObserver
+ def __init__(self,control_sending_text):
+
+ print 'just initiating'
+ self.control_sending_text=control_sending_text
+ self.content_observe=''
+ def observe(self, service, topic, extra):
+ print 'getting the signal in the python part'
+
+
+
+ if topic=="xo-message2": #it is for the execute command type'
+ service = service.QueryInterface(components.interfaces.nsIMutableArray)
+ if service.length:
+ iter = service.enumerate()
+ result = iter.getNext()
+ result = result.QueryInterface(components.interfaces.nsISupportsString)
+ self.content_observe=result.toString()
+ print 'the content in observer of xocom is ', self.content_observe
+ saveundostring=iter.getNext()
+ saveundostring=saveundostring.QueryInterface(components.interfaces.nsISupportsString)
+ saveundostring=saveundostring.toString()
+ sendingArray=['execute',self.content_observe,saveundostring]
+ self.control_sending_text(array=sendingArray,str='execute')
+
+
+class ServerThread(threading.Thread):
+ def __init__(self,port,logic):
+ threading.Thread.__init__(self)
+ self.startserver(port,logic)
+
+ def startserver(self,port,logic):
+ try:
+ self.server = Server(("127.0.0.1",port),logic)
+ self.closing = 0
+ except:
+ self.startserver(port+2,logic)
+
+ def run(self):
+ try:
+ self.server.serve_forever()
+ except:
+ if(self.closing == 0):
+ self.run()
+
+ def stop(self):
+ r = 2
diff --git a/activity/activity-socialcalc.svg b/activity/activity-socialcalc.svg
new file mode 100644
index 0000000..ca4ebff
--- /dev/null
+++ b/activity/activity-socialcalc.svg
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
+ <!ENTITY ns_svg "http://www.w3.org/2000/svg">
+ <!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
+ <!ENTITY fill_color "#FFFFFF">
+ <!ENTITY stroke_color "#000000">
+]>
+<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="48" height="48.119" viewBox="0 0 48 48.119"
+ overflow="visible" enable-background="new 0 0 48 48.119" xml:space="preserve">
+ <rect x="6" y="19" width="10" height="10" style="fill:&fill_color;;stroke:&stroke_color;;"/>
+<rect y="14" style="fill:&fill_color;;stroke:&stroke_color;;" width="48" height="2"/>
+<rect y="16" style="fill:&fill_color;;stroke:&stroke_color;;" width="48" height="2"/>
+<rect y="30" style="fill:&fill_color;;stroke:&stroke_color;;" width="48" height="2"/>
+<rect y="32" style="fill:&fill_color;;stroke:&stroke_color;;" width="48" height="2"/>
+<rect x="32" style="fill:&fill_color;;stroke:&stroke_color;;" width="2" height="48"/>
+<rect x="30" style="fill:&fill_color;;stroke:&stroke_color;;" width="2" height="48"/>
+<rect x="16" style="fill:&fill_color;;stroke:&stroke_color;;" width="2" height="48"/>
+<rect x="14" style="fill:&fill_color;;stroke:&stroke_color;;" width="2" height="48"/>
+<rect x="15" style="fill:&fill_color;;stroke:&stroke_color;;" width="2" height="48"/>
+<rect y="15" style="fill:&fill_color;;stroke:&stroke_color;;" width="48" height="2"/>
+<rect y="31" style="fill:&fill_color;;stroke:&stroke_color;;" width="48" height="2"/>
+<rect x="31" style="fill:&fill_color;;stroke:&stroke_color;;" width="2" height="48"/>
+<g>
+ <path style="fill:&fill_color;;stroke:&stroke_color;;" d="M21.388,8.767l-0.84,2.544h-1.08l2.748-8.088h1.26l2.761,8.088h-1.117l-0.864-2.544H21.388z M24.04,7.95
+ l-0.804-2.328c-0.168-0.527-0.288-1.008-0.408-1.476h-0.036c-0.108,0.468-0.24,0.972-0.396,1.464l-0.792,2.34H24.04z"/>
+</g>
+<g>
+ <path style="fill:&fill_color;;stroke:&stroke_color;;" d="M36.995,3.336c0.456-0.107,1.188-0.18,1.908-0.18c1.044,0,1.716,0.18,2.208,0.588
+ c0.42,0.312,0.684,0.792,0.684,1.429c0,0.792-0.528,1.476-1.368,1.775v0.036c0.769,0.18,1.668,0.816,1.668,2.016
+ c0,0.696-0.275,1.225-0.695,1.62c-0.553,0.517-1.465,0.756-2.784,0.756c-0.72,0-1.272-0.048-1.62-0.096V3.336z M38.039,6.648h0.948
+ c1.092,0,1.739-0.588,1.739-1.368c0-0.936-0.708-1.32-1.764-1.32c-0.479,0-0.756,0.036-0.924,0.072V6.648z M38.039,10.513
+ c0.216,0.036,0.504,0.048,0.876,0.048c1.08,0,2.076-0.396,2.076-1.572c0-1.092-0.948-1.56-2.088-1.56h-0.864V10.513z"/>
+</g>
+<g>
+ <path style="fill:&fill_color;;stroke:&stroke_color;;" d="M7.499,20.851H7.475l-1.356,0.732l-0.204-0.804l1.704-0.912h0.9v7.8h-1.02V20.851z"/>
+</g>
+<g>
+ <path style="fill:&fill_color;;stroke:&stroke_color;;" d="M5.374,42.835v-0.648l0.828-0.804c1.992-1.896,2.904-2.904,2.904-4.08c0-0.792-0.372-1.523-1.536-1.523
+ c-0.708,0-1.296,0.359-1.656,0.659l-0.336-0.743c0.528-0.444,1.308-0.792,2.208-0.792c1.668,0,2.376,1.151,2.376,2.268
+ c0,1.44-1.044,2.604-2.688,4.188l-0.612,0.575v0.024h3.492v0.876H5.374z"/>
+</g>
+</svg>
diff --git a/activity/activity.info b/activity/activity.info
new file mode 100644
index 0000000..d146347
--- /dev/null
+++ b/activity/activity.info
@@ -0,0 +1,9 @@
+[Activity]
+name = SocialCalcActivity
+service_name = com.socialtext.SocialCalcActivity
+class = SocialCalcActivity.SocialCalcActivity
+icon = activity-socialcalc
+activity_version = 5
+show_launcher = Yes
+mime_types =application/vnd.lotus-1-2-3;application/scalc;application/wk4;application/x-wk4;application/lotus123;application/x-lotus123;application/vnd.ms-excel
+
diff --git a/constants.py b/constants.py
new file mode 100644
index 0000000..6ae16a6
--- /dev/null
+++ b/constants.py
@@ -0,0 +1,88 @@
+import os
+import gtk
+from gettext import gettext as _
+
+import sugar.graphics.style
+from sugar.activity import activity
+from sugar import profile
+
+from instance import Instance
+
+class Constants:
+
+ VERSION = 8
+
+ SERVICE = "org.laptop.Map"
+ IFACE = SERVICE
+ PATH = "/org/laptop/Map"
+ activityId = None
+
+ gfxPath = os.path.join(activity.get_bundle_path(), "gfx")
+ htmlPath = os.path.join(activity.get_bundle_path(), "html")
+ iconsPath = os.path.join(activity.get_bundle_path(), "icons")
+
+ istrAnnotate = _("Edit")
+ istrSearch = _("Search")
+ istrSearchAddress = _('Find:')
+ istrSearchMedia = _("Tags:")
+ istrSaveSearch = _("Save Search")
+ istrConnecting = _("Connecting to Map Server")
+ istrZoomIn = _("Zoom In")
+ istrZoomOut = _("Zoom Out")
+ istrSaveSearch = _("Save")
+ istrDensity = _("Density")
+ istrSavedMap = _("Saved Map")
+ istrTagMap = _("Describe Map")
+ istrRemove = _("Remove Map")
+ istrCopyToClipboard = _("Copy to Clipboard")
+ istrAddMedia = _("Add Media")
+ istrAddInfo = _("Add Info")
+ istrDeleteMedia = _("Delete")
+ istrWebMedia = _("Library")
+ istrMeasure = _("Measure")
+ istrStaticMaps = _("olpcMAP.net")
+ istrPanoramio = _("Panoramio")
+ istrLocalWiki = _("LocationWiki")
+ istrWikiMapia = _("WikiMapia")
+ istrLatitude = _("Latitude:")
+ istrLongitude = _("Longitude:")
+ istrTags = _("Description:")
+ istrLang = _("lang=en")
+ LineButton = _("Add Line")
+ PolyButton = _("Add Shape")
+
+ TYPE_PHOTO = 0
+ TYPE_VIDEO = 1
+
+ ui_dim_INSET = 4
+
+ recdAlbum = "map"
+ recdLat = "lat"
+ recdLng = "lng"
+ recdDatastoreId = "datastore"
+ recdInfo = "info"
+ recdMapItem = "mapItem"
+ recdSavedMapItem = "savedMap"
+ recdInfoMarker = "infoMarker"
+ recdIcon = "icon"
+ recdZoom = "zoom"
+ recdNotes = "notes"
+ recdMapImg = "mapImg"
+ recdTags = "tags"
+ recdMapThumbImg = "mapThumbImg"
+ recdRecdId = "recdId"
+ recdRecdLat = "recdLat"
+ recdRecdLng = "recdLng"
+ recdDensity = "density"
+ recdLine = "line"
+ lineID = "lid"
+ lineColor = "lcolor"
+ lineThick = "lthickness"
+ linePts = "lpts"
+ mapLat="lat"
+ mapLng="lng"
+ mapZoom="zoom"
+
+
+ def __init__( self, ca ):
+ self.__class__.activityId = ca._activity_id
diff --git a/create-dev-env.pl b/create-dev-env.pl
new file mode 100644
index 0000000..3d8ad46
--- /dev/null
+++ b/create-dev-env.pl
@@ -0,0 +1,45 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use Cwd;
+use File::Path qw/rmtree/;
+
+my $app_dir = shift or usage();
+my $dev_dir = shift or usage();
+unless (-d $app_dir) {
+ die "No such directory: $app_dir\n";
+}
+unless (-d $dev_dir) {
+ die "No such directory: $dev_dir\n";
+}
+
+print "$app_dir => $dev_dir\n";
+
+my @files = glob("$dev_dir/*");
+for my $f (@files) {
+ (my $basename = $f) =~ s#.+/##;
+ my $app_file = "$app_dir/$basename";
+ if (-d $app_file) {
+ rmtree $app_file or die "Couldn't rmtree $app_file: $!";
+ }
+ if (-e $app_file) {
+ unlink $app_file or die "Couldn't unlink $app_file: $!";
+ }
+
+ print "Symlinking $basename\n";
+ symlink "$dev_dir/$basename" => $app_file
+ or die "Can't symlink $dev_dir/$basename => $app_file: $!";
+}
+
+exit;
+
+sub usage {
+ die <<EOT;
+USAGE: $0 <activity directory> <dev directory>
+
+This tool creates symlinks from the Activity directory into the current
+working directory. Any file or directory found in the dev directory
+will be symlinked to the Activity directory.
+
+EOT
+}
diff --git a/instance.py b/instance.py
new file mode 100644
index 0000000..8e469dc
--- /dev/null
+++ b/instance.py
@@ -0,0 +1,39 @@
+import os
+
+from sugar import profile
+from sugar import util
+from sugar.activity import activity
+import shutil
+
+
+class Instance:
+ key = profile.get_pubkey()
+ #joyride ...
+ #keyHash = util.sha_data(key)
+ #8.2...
+ #keyHash = util._sha_data(key)
+ #keyHashPrintable = util.printable_hash(keyHash)
+ nickName = profile.get_nick_name()
+
+ instanceId = None
+ instancePath = None
+ dataPath = None
+
+ def __init__(self, ca):
+ self.__class__.instanceId = ca._activity_id
+
+ self.__class__.instancePath = os.path.join(ca.get_activity_root(), "instance")
+ recreateTmp()
+
+ self.__class__.dataPath = os.path.join(ca.get_activity_root(), "data")
+ recreateData()
+
+
+def recreateTmp():
+ if (not os.path.exists(Instance.instancePath)):
+ os.makedirs(Instance.instancePath)
+
+
+def recreateData():
+ if (not os.path.exists(Instance.dataPath)):
+ os.makedirs(Instance.dataPath)
diff --git a/intero.py b/intero.py
new file mode 100644
index 0000000..db53207
--- /dev/null
+++ b/intero.py
@@ -0,0 +1,37 @@
+# Ability to read single sheet Lotus .wk4 files in SocialCalc added. Developed by Vijit Singh,
+# Software Engineer at SEETA (http://seeta.in) under the guidance of Manusheel Gupta.
+# Ability to read single sheet Excel .xls files in SocialCalc added. Developed by Mahesh Chand Sharma from SEETA (http://seeta.in) with pointers from Vijit Singh,
+# Software Engineer at SEETA (http://seeta.in) under the guidance of Manusheel Gupta.
+# For getting involved in the development of SocialCalc on Sugar, or on any questions related to it, please e-mail at socialcalc<dot>sugar<at>seeta<dot>in.
+# For posting a feature request/bug, please use http://testtrack.seeta.in.
+# File author - Vijit Singh
+
+
+
+import interoperability
+from interoperability import lotus_wk4
+from interoperability.xls import workbook
+
+
+def convert(byte_string,file_extension):
+ if file_extension == '.wk4':
+ result=lotus_wk4.wk4_to_scalc(byte_string)
+
+ elif file_extension == '.xls':
+ result=workbook.bin2data(byte_string)
+ if result=='file not in correct format': ## To check that file is in the correct readable format
+ print 'BEWARE : file not in correct format, it is not the correct xls format, check the file\n'
+ result=''
+
+
+ #print result
+ return result
+
+
+def check_file_extension(filename):
+ if ('.wks' in filename or '.wk4' in filename):
+ return (True, '.wk4')
+ elif('.xls' in filename or '.xlw' in filename):
+ return (True,'.xls')
+ else :
+ return ( False, '')
diff --git a/interoperability/__init__.py b/interoperability/__init__.py
new file mode 100644
index 0000000..2ae2839
--- /dev/null
+++ b/interoperability/__init__.py
@@ -0,0 +1 @@
+pass
diff --git a/interoperability/__init__.pyo b/interoperability/__init__.pyo
new file mode 100644
index 0000000..e73f1a9
--- /dev/null
+++ b/interoperability/__init__.pyo
Binary files differ
diff --git a/interoperability/lotus_wk4.py b/interoperability/lotus_wk4.py
new file mode 100644
index 0000000..9dacd58
--- /dev/null
+++ b/interoperability/lotus_wk4.py
@@ -0,0 +1,291 @@
+import struct
+# Ability to read single sheet Lotus .wk4 files in SocialCalc added. Developed by Vijit Singh,
+# Software Engineer at SEETA (http://seeta.in) under the guidance of Manusheel Gupta.
+# For getting involved in the development of SocialCalc on Sugar, or on any questions related to it, please e-mail at socialcalc<dot>sugar<at>seeta<dot>in.
+# For posting a feature request/bug, please use http://testtrack.seeta.in.
+# File Author - Vijit Singh
+
+def col_no_to_alphabet(no):
+
+ alpha_1=chr(ord('A')+(no/26)-1)
+ alpha_0=chr(ord('A')+(no%26))
+
+ #print 'no received is',no
+
+ if no/26==0:
+ return alpha_0
+
+ else:
+ return alpha_1+alpha_0
+
+
+
+
+
+
+def wk4_to_scalc(byte_string):
+ i=0 # pointer to the character to be read
+ l=len(byte_string) # length of the byte array
+ # print byte_string
+
+ #### Creating the strings to be sent back as result- converted strings######
+
+ result_string='' # main string
+ sheet_string=''## I think this string contains the values of various cells and it is what is loaded into the spreadsheet
+ edit_string='' ## This string tells the positions(parts) of spreadsheet which are visible at the time of saving, I mean the cell at which mouse was there et al
+ audit_string='' ## it contains the actions which were taken, it is req. to maintain undo stack, not sure whether req at this juncture, still adding....
+ ## ....becoz don't know whether spreadsheet can be loaded without it or not.
+ multipartBoundary_string="SocialCalcSpreadsheetControlSave"
+
+ #### Initiating some of these strings######
+ sheet_string+='version:1.5\n'
+
+
+ #### Some constants which will be used during string preparation######
+ add_center_string_flag=False ## These 2 flags take care whether we should add the following string cellformat:2:right or cellformat:1:middle in the
+ add_right_string_flag=False ## sheet_string, we might not require them over the time, and might just add these strings everytime.
+
+ max_col=0 ## Takes care of the max. value of row and col till which sheet is there, max dimensions of the sheet
+ max_row=0
+
+ while(i<l):
+
+ #read instantly the header on the basis of the value of i
+ header=byte_string[i:i+4]
+
+ #type
+ record_type=header[0:2]
+ # print record_type
+ # print 'should be equal to',"\x16\x00"
+
+ #length
+ record_length=header[2:4]
+ r_length=struct.unpack("i",record_length[0:2]+"\x00\x00") # converting it to int value
+ r_length=r_length[0]
+
+ i=i+4
+
+ #fetching the record body and incrementing i
+ record_body=byte_string[i:i+r_length] # as r_length is a tuple
+
+ i=i+r_length
+
+
+
+ ######### Starting the switch cases- if elif in python to test the record_type and take appropriate actions##############
+
+ ## testing it for BOF
+ if record_type=="\x00\x00": ## NOTE: not doing anything for now, will take steps when complexity will inc
+ #print 'it is BOF and the length is ',r_length
+
+ ## To decode the max dimensions of the sheet
+ if max_row==0: # so that we are not setting it again when bof is encountered again, might also check the length instead
+ max_row=(struct.unpack("i",record_body[8]+record_body[9]+"\x00\x00")[0])+1 ## it reverses on its own
+ max_col=struct.unpack("i",record_body[11:12]+"\x00\x00\x00")[0]
+ max_col=col_no_to_alphabet(max_col)
+
+ pass
+
+ ## testing it for TREAL nos.
+ elif record_type=="\x17\x00":
+
+ #print 'in real no test, should be equal to',"\x16\x00"
+
+ # To deode row and column
+
+ row=struct.unpack("i",record_body[0:2]+"\x00\x00")[0]
+ row=row+1 # as row starts from 1 but it returns according to index 0 , so to compensate
+ worksheet=struct.unpack("i",record_body[2:3]+"\x00\x00\x00")[0]
+ if worksheet>0: # NOTE: Decodes only the first spreadsheet in case multiple worksheets are present; need to find a proper solution for this
+ break
+ col=struct.unpack("i",record_body[3:4]+"\x00\x00\x00")[0]
+ col_alphabetical=col_no_to_alphabet(col)
+
+ #print "row ",row,"worksheet ",worksheet,"col ",col
+
+ record_body=record_body[4:len(record_body)]
+
+
+ record_body=record_body[::-1] ## reverse the hex string leaving each byte intact
+
+ exponent=struct.unpack("i",record_body[1:2]+record_body[0:1]+"\x00\x00")
+ exponent=exponent[0]
+ #print "exponent is",exponent
+ sign=exponent & 32768 ## because 0x8000= 32768 ## getting the sign bit
+ exponent=exponent & 32767
+
+ mantissa1=struct.unpack("i",record_body[3:4]+record_body[2:3]+"\x00\x00")
+ mantissa2=struct.unpack("i",record_body[5:6]+record_body[4:5]+"\x00\x00")
+ mantissa3=struct.unpack("i",record_body[7:8]+record_body[6:7]+"\x00\x00")
+ mantissa4=struct.unpack("i",record_body[9:10]+record_body[8:9]+"\x00\x00")
+ mantissa1=mantissa1[0]
+ mantissa2=mantissa2[0]
+ mantissa3=mantissa3[0]
+ mantissa4=mantissa4[0]
+## print 'man1=',mantissa1
+## print 'man2=',mantissa2
+
+
+ mantissa_value=1.0
+ mantissa1=mantissa1<<1 # to remove the not needed 1st one
+ #mantissa1>>1
+
+ for j in range(1,15):
+ #print "mantissa is ",mantissa1<<1
+ #print
+
+ bit=(mantissa1)&32768
+ mantissa1=mantissa1<<1
+## print 'bit is',bit
+ if bit==32768:
+ # print 'in mantissa addn'
+ # print (1.0/pow(2,j))
+ mantissa_value+=(1.0/pow(2,j))
+
+
+ for j in range(1,16):
+
+ bit=(mantissa2)&32768
+ mantissa2=mantissa2<<1
+## print 'bit is',bit
+ if bit==32768:
+ mantissa_value+=(1.0/pow(2,15+j)) ## As, the distance should be more now
+
+ for j in range(1,16):
+ bit=(mantissa3)&32768
+ mantissa3=mantissa3<<1
+## print 'bit is',bit
+ if bit==32768:
+ mantissa_value+=(1.0/pow(2,31+j)) ## As, the distance should be more now
+
+ for j in range(1,16):
+ bit=(mantissa4)&32768
+ mantissa4=mantissa4<<1
+## print 'bit is',bit
+ if bit==32768:
+ mantissa_value+=(1.0/pow(2,47+j)) ## As, the distance should be more now
+
+ # print mantissa_value
+ # Calculating the value of the TREAL number
+ #print "sign ",pow(-1,sign)," exp ",pow(2,(exponent-16383))," manti ",mantissa_value
+ treal_no=pow(-1,sign)*pow(2,(exponent-16383))*(mantissa_value)
+
+
+ ############################ Saving the no and its coordinates in the string format#######################################
+ #### The format for sheet string would be cell:A1:v:1 ,i.e. cell:colrow:v:value_at_that_cell
+ #### The format for audit string would be set AB24 value n 333.9898989, i.e. set colrow value n value_at_that_cell
+
+ sheet_string+='cell:'+str(col_alphabetical)+str(row)+':v:'+str(treal_no)+'\n'
+ audit_string+='set '+str(col_alphabetical)+str(row)+' value n '+str(treal_no)+'\n'
+
+ #print " no is ",treal_no," present at : row ",row,"worksheet ",worksheet,"col ",col
+
+ ### for testing labels (strings)
+ elif record_type=="\x16\x00":
+
+ # To deode row and column
+
+ row=struct.unpack("i",record_body[0:2]+"\x00\x00")[0]
+ row=row+1 # as row starts from 1 but it returns according to index 0 , so to compensate
+ worksheet=struct.unpack("i",record_body[2:3]+"\x00\x00\x00")[0]
+ if worksheet>0:
+ break
+ col=struct.unpack("i",record_body[3:4]+"\x00\x00\x00")[0]
+ col_alphabetical=col_no_to_alphabet(col)
+ #print "row ",row,"worksheet ",worksheet,"col ",col
+
+ record_body=record_body[4:len(record_body)]
+
+ ## justification
+ #print "just as such is ",record_body[0]
+ justification=ord(record_body[0])
+
+ ##label
+# label=record_body[1:len(record_body)] ## NOTE: using this assignment will transfer the hex-string itself to the browser to display. In case,
+ ## browser gives error to display it , comment this line and uncomment the loop below
+ label=''
+ for j in range(1,len(record_body)-1): ## seems to be needed.
+
+ c=chr(ord(record_body[j]))
+ if c==':': # IMP: because these strings are used in javascript part of socialcalc for other purposes
+ c='\c'
+ elif c=='\\':
+ c='\\b' ## NOTE: made changes here according to .xls, just in case lotus interoperability shows some kind of problem, reverse this change
+ elif c=='\n':
+ c='\\n'
+ label+=c
+
+ ############################ Saving the no and its coordinates in the string format#######################################
+ #### The format for sheet string would be cell:A1:v:1 ,i.e. cell:colrow:v:value_at_that_cell
+ #### The format for audit string would be set AB24 value n 333.9898989, i.e. set colrow value n value_at_that_cell
+
+ sheet_string+='cell:'+str(col_alphabetical)+str(row)+':t:'+label
+ if justification=="'":
+ sheet_string+='\n'
+ elif justification=='^':
+ sheet_string+=':cf:1\n'
+ audit_string+='set '+str(col_alphabetical)+str(row)+' cellformat center'+'\n' # this line is added afterwards, so incase the code creates some problem , check this line
+ add_center_string_flag=True
+ elif justification=='"':
+ sheet_string+=':cf:2\n'
+ audit_string+='set '+str(col_alphabetical)+str(row)+' cellformat right'+'\n' # this line is added afterwards, so incase the code creates some problem , check this line
+
+ add_right_string_flag=True
+ else :
+ sheet_string+='\n'
+ audit_string+='set '+str(col_alphabetical)+str(row)+' value t '+label+'\n'
+
+ #print "just ",justification," label ",label, " present at : row ",row,"worksheet ",worksheet,"col ",col
+
+
+
+ ###### Finalizing the strings before returning#########
+ sheet_string+='sheet:c:'+str(max_col)+':r:'+str(max_row)+'\n'
+ if add_center_string_flag:
+ sheet_string+='cellformat:1:center\n'
+ if add_right_string_flag:
+ sheet_string+='cellformat:2:right\n'
+
+ ## This edit_string is made like this just for now, over the time, atleast the sort thing would be needed to be dynamically assigned.
+ ## The colpane, ecell and rowpane, need not be changed because, it tells when to keep the focus when restarted, and we don't have any such requirements.
+
+ edit_string='version:1.0\nrowpane:0:1:26\ncolpane:0:1:10\necell:A4\nsort::-1:up::::\ngraph:range:undefined:type::minmax:undefined,undefined,undefined,undefined'
+
+ result_string+="socialcalc:version:1.0\n" + "MIME-Version: 1.0\nContent-Type: multipart/mixed; boundary="+multipartBoundary_string+ "\n" +\
+ "--" + multipartBoundary_string + "\nContent-type: text/plain; charset=UTF-8\n\n" +\
+ "# SocialCalc Spreadsheet Control Save\nversion:1.0\npart:sheet\npart:edit\npart:audit\n" +\
+ "--" + multipartBoundary_string + "\nContent-type: text/plain; charset=UTF-8\n\n" +\
+ sheet_string +\
+ "--" + multipartBoundary_string + "\nContent-type: text/plain; charset=UTF-8\n\n" +\
+ edit_string +\
+ "--" + multipartBoundary_string + "\nContent-type: text/plain; charset=UTF-8\n\n" +\
+ audit_string +\
+ "--" + multipartBoundary_string + "--\n"
+
+ return result_string
+
+
+
+
+
+
+######## For debugging and testing purposes only, the following code should be commented when using in sync with the socialcalc code#############
+
+
+def main():
+ a="\x17\x00\x0e\x00\x2f\x00\x01\x01\x84\x12\x64\x1b\x7b\xf4\x06\xca\x05\x40\x16\x00\x0d\x00\x2f\x00\x01\x01\x27\x20\x42\x41\x53\x4b\x45\x54\x00"
+ #a="\x17\x00\x0a\x00\xcb\xa1\x45\xb6\xf3\x7d\x9c\xad\x0c\x40"
+ #f=open('check5.wk4','rb')
+ #a=f.read()
+ s=wk4_to_scalc(a)
+ print s
+ #f.close()
+ #print "no is", no
+
+
+#main()
+
+
+
+
+
diff --git a/interoperability/lotus_wk4.pyo b/interoperability/lotus_wk4.pyo
new file mode 100644
index 0000000..68f6a30
--- /dev/null
+++ b/interoperability/lotus_wk4.pyo
Binary files differ
diff --git a/interoperability/xls/__init__.py b/interoperability/xls/__init__.py
new file mode 100644
index 0000000..2ae2839
--- /dev/null
+++ b/interoperability/xls/__init__.py
@@ -0,0 +1 @@
+pass
diff --git a/interoperability/xls/__init__.pyo b/interoperability/xls/__init__.pyo
new file mode 100644
index 0000000..e9c71cf
--- /dev/null
+++ b/interoperability/xls/__init__.pyo
Binary files differ
diff --git a/interoperability/xls/compound.py b/interoperability/xls/compound.py
new file mode 100644
index 0000000..13c02f3
--- /dev/null
+++ b/interoperability/xls/compound.py
@@ -0,0 +1,127 @@
+#from os import abort
+def hexa(s): # return the hexadecimal euvalent of sring
+ p=1
+ ans=0
+ for c in s:
+ ans=ans+p*ord(c)
+ p*=256
+ return ans
+def integer(s): # return the integer eqvalent in big-endian signed format
+ p=1
+ ans=0
+ for c in s:
+ ans=ans+p*ord(c)
+ p*=256
+ if ord(s[-1])<=0x7f:return ans
+ return int(-1*((256**len(s))-ans))
+
+def offset(sid, sec_size):
+ return 512 + sec_size*sid # 512 header size
+
+def readname(st):
+ b=integer(st[64:66]) - 2
+ return st[:b:2]
+
+def soffset(sid, short_sec_size):
+ return short_sec_size*sid
+
+def return_wbk(s):
+ if hexa(s[:8])!=0xe11ab1a1e011cfd0: # unique indentifier for CDFF
+ return 'file not in correct format'
+
+ # reading the header
+ sec_size = 2**integer(s[30:32]) # typically 512
+ short_sec_size = 2**integer(s[32:34]) # typiclly 64
+ sat_sectors = integer(s[44 : 48])
+ dir_secid = integer(s[48 : 52])
+ standard_strm_size = integer(s[56 : 60])
+ ssat_secid = integer(s[60 : 64])
+ ssat_sectors=integer(s[64 : 68])
+ msat_secid = integer(s[68 : 72])
+ msat_sectors = integer(s[72 : 76])
+ init_msat = s[76 : 512]
+
+
+ # building MSAT
+ msat=[]
+ for i in range(0, 436, 4):
+ msat+=[integer(init_msat[i : i+4])]
+ for i in range(0, msat_sectors):
+ t=offset(msat_secid, sec_size)
+ sec=s[t : t+sec_size]
+ for j in range(0, sec_size-4, 4):
+ msat+=[integer(sec[j : j+4])]
+ msat_secid=integer(sec[508 : 512])
+
+ #building SAT
+ sat=[]
+ for i in range (0, sat_sectors):
+ t = offset(msat[i], sec_size)
+ sec = s[t : t+sec_size]
+ for j in range(0, sec_size, 4):
+ sat+=[integer(sec[j : j+4])]
+
+
+ #building SSAT
+ ssat=[]
+ for i in range (0, ssat_sectors):
+ t = offset(ssat_secid, sec_size)
+ if t==-2:break
+ sec = s[t : t+sec_size]
+ for j in range(0, sec_size, 4):
+ ssat+=[integer(sec[j : j+4])]
+ ssat_secid=sat[ssat_secid]
+
+
+ # building directory stream
+ dir_stream='' # size of this stream is stored in root entry
+ while dir_secid!=-2:
+ t = offset(dir_secid, sec_size)
+ dir_stream += s[t : t+sec_size]
+ dir_secid=sat[dir_secid]
+
+
+
+ # reading dir_stream
+
+
+ # (1) reading root storage entry, only data of use is scaned
+ rootname_len=integer(dir_stream[64:66])
+ rootname = dir_stream[:rootname_len]
+ rootnode_dirid = integer(dir_stream[76 : 80])
+ sstream_container_secid = integer(dir_stream[116 : 120])
+ sstream_size = integer(dir_stream[120 : 124])
+
+ sstream_container='' #building short sector stream container
+ while sstream_container_secid!=-2:
+ t=offset(sstream_container_secid, sec_size)
+ sstream_container += s[t : t+ sec_size]
+ sstream_container_secid=sat[sstream_container_secid]
+
+ # (2) Reaching to workbook directory
+ dir_entry_count = len(dir_stream)/128
+ for i in range(1, dir_entry_count):
+ dir_entry = dir_stream[i*128 : (i+1)*128]
+ if readname(dir_entry) == 'Workbook':
+ wbk_entry = dir_entry
+ break
+
+ # (3) Reading the workbook entry
+ wbk_size = integer(wbk_entry[120 : 124])
+ sec_id = integer(wbk_entry[116 : 120])
+ wbk = ''
+ if wbk_size < standard_strm_size: # wbk is saved in short stream container
+ while sec_id != -2:
+ t = soffset(sec_id, short_sec_size)
+ wbk += sstream_container[t : t + short_sec_size]
+ sec_id = ssat[sec_id]
+
+ else:
+ while sec_id != -2:
+ t = offset(sec_id, sec_size)
+ wbk += s[t : t + sec_size]
+ sec_id = sat[sec_id]
+ return wbk
+
+ # wbk is the user stresm (workbook
+
diff --git a/interoperability/xls/compound.pyo b/interoperability/xls/compound.pyo
new file mode 100644
index 0000000..7f2ecf1
--- /dev/null
+++ b/interoperability/xls/compound.pyo
Binary files differ
diff --git a/interoperability/xls/convert_to_scalcstring.py b/interoperability/xls/convert_to_scalcstring.py
new file mode 100644
index 0000000..66cd99d
--- /dev/null
+++ b/interoperability/xls/convert_to_scalcstring.py
@@ -0,0 +1,372 @@
+# Ability to read single sheet Excel .xls files in SocialCalc added. Developed by Mahesh Chand Sharma from SEETA (http://seeta.in) with pointers from Vijit Singh,
+# Software Engineer at SEETA (http://seeta.in) under the guidance of Manusheel Gupta.
+# For getting involved in the development of SocialCalc on Sugar, or on any questions related to it, please e-mail at socialcalc<dot>sugar<at>seeta<dot>in.
+#For posting a feature request/bug, please use http://testtrack.seeta.in.
+# File Author - Vijit Singh
+
+
+#### Creating the strings to be sent back as result- converted strings######
+
+result_string='' # main string
+sheet_string=''## I think this string contains the values of various cells and it is what is loaded into the spreadsheet
+edit_string='' ## This string tells the positions(parts) of spreadsheet which are visible at the time of saving, I mean the cell at which mouse was there et al
+audit_string='' ## it contains the actions which were taken, it is req. to maintain undo stack, not sure whether req at this juncture, still adding....
+ ## ....becoz don't know whether spreadsheet can be loaded without it or not.
+multipartBoundary_string="SocialCalcSpreadsheetControlSave"
+
+
+# dictionaries and list for maintianig the format_order and which of the formats are to be included
+font_align={}
+font_align_sorted=[]
+ver_align={'bottom':0,'middle':0,'top':0}
+ver_align_sorted=[]
+hor_align={'center':0,'left':0,'right':0}
+hor_align_sorted=[]
+
+def col_no_to_alphabet(no):
+
+ alpha_1=chr(ord('A')+(no/26)-1)
+ alpha_0=chr(ord('A')+(no%26))
+
+ #print 'no received is',no
+
+ if no/26==0:
+ return alpha_0
+
+ else:
+ return alpha_1+alpha_0
+
+
+def add_cell_format(format_info,font_size,r,col_alphabetical):
+
+ global sheet_string
+ global audit_string
+
+ font_family='' # NULL for now will take the value accordingly when code would be written for it
+
+ font_changed=False
+ if font_size!=10:
+ font_changed=True
+ if font_size==26:
+ font_size=24
+
+
+
+ # checking vertical alignment
+ vert_align_chars=format_info[5:7]
+ if vert_align_chars!='00':
+ if vert_align_chars=='01': # top
+ if ver_align['top']==0:
+ local_len=len(ver_align_sorted)
+ ver_align_sorted.append('top')
+ local_len+=1
+ ver_align['top']=local_len
+
+ sheet_string+=':l:'+str(ver_align['top'])
+ audit_string+='set '+str(col_alphabetical)+str(r+1)+' layout padding:* * * *;vertical-align:top;'+'\n'
+
+ elif vert_align_chars=='10': # middle
+ if ver_align['middle']==0:
+ local_len=len(ver_align_sorted)
+ ver_align_sorted.append('middle')
+ local_len+=1
+ ver_align['middle']=local_len
+
+ sheet_string+=':l:'+str(ver_align['middle'])
+ audit_string+='set '+str(col_alphabetical)+str(r+1)+' layout padding:* * * *;vertical-align:middle;'+'\n'
+
+ elif vert_align_chars=='11': # bottom
+ if ver_align['bottom']==0:
+ local_len=len(ver_align_sorted)
+ ver_align_sorted.append('bottom')
+ local_len+=1
+ ver_align['bottom']=local_len
+
+ sheet_string+=':l:'+str(ver_align['bottom'])
+ audit_string+='set '+str(col_alphabetical)+str(r+1)+' layout padding:* * * *;vertical-align:bottom;'+'\n'
+
+
+ # checking font
+ font_chars=format_info[0:2] # 0th for bold and 1st for italic
+ if font_chars!='00': # normal font_type
+
+ font_string=make_font_string(font_family,'',font_size)
+ if font_string not in font_align:
+ local_len=len(font_align_sorted)
+ font_align_sorted.append(font_string)
+ local_len+=1
+ font_align[font_string]=local_len
+
+ sheet_string+=':f:'+str(font_align[font_string])
+ audit_string+='set '+str(col_alphabetical)+str(r+1)+' font '+font_string+'\n'
+
+ if font_chars=='01': # italic
+
+ font_string=make_font_string(font_family,'italic normal',font_size)
+ if font_string not in font_align:
+ local_len=len(font_align_sorted)
+ font_align_sorted.append(font_string)
+ local_len+=1
+ font_align[font_string]=local_len
+
+ sheet_string+=':f:'+str(font_align[font_string])
+ audit_string+='set '+str(col_alphabetical)+str(r+1)+' font '+font_string+'\n'
+
+ elif font_chars=='10': # bold
+ font_string=make_font_string(font_family,'normal bold',font_size)
+ if font_string not in font_align:
+ local_len=len(font_align_sorted)
+ font_align_sorted.append(font_string)
+ local_len+=1
+ font_align[font_string]=local_len
+
+ sheet_string+=':f:'+str(font_align[font_string])
+ audit_string+='set '+str(col_alphabetical)+str(r+1)+' font '+font_string+'\n'
+
+
+ elif font_chars=='11': # italic bold
+ font_string=make_font_string(font_family,'italic bold',font_size)
+ if font_string not in font_align:
+ local_len=len(font_align_sorted)
+ font_align_sorted.append(font_string)
+ local_len+=1
+ font_align[font_string]=local_len
+
+ sheet_string+=':f:'+str(font_align[font_string])
+ audit_string+='set '+str(col_alphabetical)+str(r+1)+' font '+font_string+'\n'
+
+
+ # checking horizontal alignment
+ hor_align_chars=format_info[3:5] # 01 for left, 10 for center and 11 for right
+ if hor_align_chars!='00':
+ if hor_align_chars=='01': # left
+ if hor_align['left']==0:
+ local_len=len(hor_align_sorted)
+ hor_align_sorted.append('left')
+ local_len+=1
+ hor_align['left']=local_len
+
+ sheet_string+=':cf:'+str(hor_align['left'])
+ audit_string+='set '+str(col_alphabetical)+str(r+1)+' cellformat left'+'\n'
+
+ elif hor_align_chars=='10': # center
+ if hor_align['center']==0:
+ local_len=len(hor_align_sorted)
+ hor_align_sorted.append('center')
+ local_len+=1
+ hor_align['center']=local_len
+
+ sheet_string+=':cf:'+str(hor_align['center'])
+ audit_string+='set '+str(col_alphabetical)+str(r+1)+' cellformat center'+'\n'
+
+ elif hor_align_chars=='11': # right
+ if hor_align['right']==0:
+ local_len=len(hor_align_sorted)
+ hor_align_sorted.append('right')
+ local_len+=1
+ hor_align['right']=local_len
+
+ sheet_string+=':cf:'+str(hor_align['right'])
+ audit_string+='set '+str(col_alphabetical)+str(r+1)+' cellformat right'+'\n'
+
+
+def make_font_string(font_family,font_type,font_size):
+ font_string=''
+ if font_type=='':
+ font_string+='* '
+ else:
+ font_string+=font_type+' '
+
+ if font_size==10:
+ font_string+='* '
+ else:
+ font_string+=str(font_size)+'pt '
+
+ if font_family=='':
+ font_string+='*'
+ else:
+ font_string+=font_family
+
+ return font_string
+
+
+def add_cell_format_abbr():
+
+ global sheet_string
+ global audit_string
+
+ # adding abbreviations for horizontal alignment
+ for i in range(len(hor_align_sorted)):
+ sheet_string+='cellformat:'+str(i+1)+':'+hor_align_sorted[i]+'\n'
+
+ # adding abbreviations for font
+ for i in range(len(font_align_sorted)):
+ sheet_string+='font:'+str(i+1)+':'+font_align_sorted[i]+'\n'
+
+ # adding abbreviations for vertical alignment
+ for i in range(len(ver_align_sorted)):
+ sheet_string+='layout:'+str(i+1)+':padding:* * * *;vertical-align:'+ver_align_sorted[i]+';\n'
+
+
+def add_col_width(workbook_col_widths,sheet_no):
+
+ global sheet_string
+ global audit_string
+
+ for c in range(len(workbook_col_widths[sheet_no])):
+
+ if workbook_col_widths[sheet_no][c]!=8:
+ col_alphabetical=str(col_no_to_alphabet(c))
+ width=str((workbook_col_widths[sheet_no][c])*10)
+ sheet_string+='col:'+col_alphabetical+':w:'+width+'\n'
+ audit_string+='set '+ col_alphabetical+' width '+width+'\n'
+
+def workbook_data_to_scalc_string(workbook_data,workbook_col_widths,sheet_no=0):
+ ## the sheet_no starts from 0 with the 1st sheet placed at 0th position, and it denotes the sheet whose data is to be shown
+
+
+ global result_string
+ global sheet_string
+ global audit_string
+ global edit_string
+ global multipartBoundary_string
+
+ #### Initiating some of these strings######
+ sheet_string+='version:1.5\n'
+
+ #### Some constants which will be used during string preparation######
+ add_center_string_flag=False ## These 2 flags take care whether we should add the following string cellformat:2:right or cellformat:1:middle in the
+ add_right_string_flag=False ## sheet_string, we might not require them over the time, and might just add these strings everytime.
+
+
+ max_col=0 ## Takes care of the max. value of row and col till which sheet is there, max dimensions of the sheet
+ max_row=0
+
+ ## to know the max rows and col
+ max_row=len(workbook_data[sheet_no])
+ max_col=len(workbook_data[sheet_no][max_row-1])
+
+
+ for r in range(len(workbook_data[sheet_no])):
+ for c in range(len(workbook_data[sheet_no][r])):
+ info=workbook_data[sheet_no][r][c]
+ if info==(): # for empty cell
+ continue
+ elif info[1]=='i': # for integer
+ ############################ Saving the no and its coordinates in the string format#######################################
+ #### The format for sheet string would be cell:A1:v:1 ,i.e. cell:colrow:v:value_at_that_cell
+ #### The format for audit string would be set AB24 value n 333.9898989, i.e. set colrow value n value_at_that_cell
+
+ col_alphabetical=col_no_to_alphabet(c)
+ sheet_string+='cell:'+str(col_alphabetical)+str(r+1)+':v:'+str(info[0]) ## here the row needs to be incremented by 1 as it starts from 1 in scalc
+ audit_string+='set '+str(col_alphabetical)+str(r+1)+' value n '+str(info[0])+'\n'
+
+ elif info[1]=='f': # for float, same as integer
+ ############################ Saving the no and its coordinates in the string format#######################################
+ #### The format for sheet string would be cell:A1:v:1 ,i.e. cell:colrow:v:value_at_that_cell
+ #### The format for audit string would be set AB24 value n 333.9898989, i.e. set colrow value n value_at_that_cell
+
+ col_alphabetical=col_no_to_alphabet(c)
+ sheet_string+='cell:'+str(col_alphabetical)+str(r+1)+':v:'+str(info[0]) ## here the row needs to be incremented by 1 as it starts from 1 in scalc
+ audit_string+='set '+str(col_alphabetical)+str(r+1)+' value n '+str(info[0])+'\n'
+
+ elif info[1]=='s': # for string
+
+
+ col_alphabetical=col_no_to_alphabet(c)
+ # replacing the character ':' with '\c' and '\\' with '\\b' and '\n' with '\\n' as these characters are used internally in socialcalc
+ label=''
+ for j in range(len(info[0])): ## seems to be needed.
+
+ ch=chr(ord(info[0][j]))
+ if ch==':': # IMP: because these strings are used in javascript part of socialcalc for other purposes
+ ch='\c'
+ elif ch=='\\':
+ ch='\\b'
+ elif ch=='\n':
+ ch='\\n'
+ label+=ch
+
+
+ sheet_string+='cell:'+str(col_alphabetical)+str(r+1)+':t:'+label
+ audit_string+='set '+str(col_alphabetical)+str(r+1)+' value t '+label+'\n'
+
+
+ elif info[1]=='for': #for formula
+
+ col_alphabetical=col_no_to_alphabet(c)
+ formula_type=info[3]
+ formula_string2=info[4]
+ formula_result=info[0]
+
+ formula_string=''
+ for j in range(len(formula_string2)): ## seems to be needed.
+
+ ch=chr(ord(formula_string2[j]))
+ if ch==':': # IMP: because these strings are used in javascript part of socialcalc for other purposes
+ ch='\c'
+ elif ch=='\\':
+ ch='\\b'
+ elif ch=='\n':
+ ch='\\n'
+ formula_string+=ch
+
+ if formula_type=='f' or formula_type=='i':
+ formula_type='n'
+ elif formula_type=='s':
+ formula_type='t'
+ elif formula_type=='b':
+ formula_type='nl'
+ elif formula_type=='e':
+ formula_type='e'+str(formula_result)
+ formula_string+=':e:'+str(formula_result)
+ formula_result=''
+ sheet_string+='cell:'+str(col_alphabetical)+str(r+1)+':vtf:'+formula_type+':'+str(formula_result)+':'+formula_string ## TODO: code for date/time fns
+ audit_string+='set '+str(col_alphabetical)+str(r+1)+' formula '+formula_string+'\n'
+
+
+
+ ## call to extract format information for each cell
+ add_cell_format(info[2][0],info[2][1],r,col_alphabetical)
+
+ # adding '\n' at the last of the sheet_string since it is required for each cell
+ sheet_string+='\n'
+
+ ####### End of looping over each cell element#####
+
+ ###### Finalizing the strings before returning#########
+
+ # to add the width of the columns
+ add_col_width(workbook_col_widths,sheet_no)
+
+ # to add the no. of columns and rows in the sheet
+ sheet_string+='sheet:c:'+str(max_col)+':r:'+str(max_row)+'\n'
+
+ # to add abbreviations of the type of format used
+ add_cell_format_abbr()
+
+ ## This edit_string is made like this just for now, over the time, atleast the sort thing would be needed to be dynamically assigned.
+ ## The colpane, ecell and rowpane, need not be changed because, it tells when to keep the focus when restarted, and we don't have any such requirements.
+
+ edit_string='version:1.0\nrowpane:0:1:26\ncolpane:0:1:10\necell:A4\nsort::-1:up::::\ngraph:range:undefined:type::minmax:undefined,undefined,undefined,undefined'
+
+ result_string+="socialcalc:version:1.0\n" + "MIME-Version: 1.0\nContent-Type: multipart/mixed; boundary="+multipartBoundary_string+ "\n" +\
+ "--" + multipartBoundary_string + "\nContent-type: text/plain; charset=UTF-8\n\n" +\
+ "# SocialCalc Spreadsheet Control Save\nversion:1.0\npart:sheet\npart:edit\npart:audit\n" +\
+ "--" + multipartBoundary_string + "\nContent-type: text/plain; charset=UTF-8\n\n" +\
+ sheet_string +\
+ "--" + multipartBoundary_string + "\nContent-type: text/plain; charset=UTF-8\n\n" +\
+ edit_string +\
+ "--" + multipartBoundary_string + "\nContent-type: text/plain; charset=UTF-8\n\n" +\
+ audit_string +\
+ "--" + multipartBoundary_string + "--\n"
+
+ return result_string
+
+
+
+
+
+
+
+
diff --git a/interoperability/xls/convert_to_scalcstring.pyo b/interoperability/xls/convert_to_scalcstring.pyo
new file mode 100644
index 0000000..36d16a7
--- /dev/null
+++ b/interoperability/xls/convert_to_scalcstring.pyo
Binary files differ
diff --git a/interoperability/xls/function.py b/interoperability/xls/function.py
new file mode 100644
index 0000000..4bef80b
--- /dev/null
+++ b/interoperability/xls/function.py
@@ -0,0 +1,246 @@
+# Ability to read single sheet Excel .xls files in SocialCalc added. Developed by Mahesh Chand Sharma from SEETA (http://seeta.in) with pointers from Vijit Singh,
+# Software Engineer at SEETA (http://seeta.in) under the guidance of Manusheel Gupta.
+# For getting involved in the development of SocialCalc on Sugar, or on any questions related to it, please e-mail at socialcalc<dot>sugar<at>seeta<dot>in.
+# For posting a feature request/bug, please use http://testtrack.seeta.in.
+# File Author - Mahesh Chand Sharma
+
+
+from sugar.activity import activity
+from compound import integer, hexa
+global err_value
+err_value = ['']*(0x2A +1)
+err_value[0x00] = '#NULL!'
+err_value[0x07] = '#DIV/0!'
+err_value[0x0F] = '#VALUE'
+err_value[0x17] = '#REF!'
+err_value[0x1D] = '#NAME?'
+err_value[0x24] = '#NUM!'
+err_value[0x2A] = '#N/A!'
+def read_string(wbk, pos, len_size):
+ save=pos
+ ln=integer(wbk[pos:pos+len_size])
+ pos+=len_size
+ flag=integer(wbk[pos:pos+1])
+ pos+=1
+ rt = 0
+ sz = 0
+ if flag&8==8:
+ rt = integer(wbk[pos : pos+2])
+ pos+=2
+ if flag&4==4:
+ sz = integer(wbk[pos : pos+4])
+ pos+=4
+ if flag&1==1:
+ w = wbk[pos:pos+2*ln:2]
+ pos = pos+2*ln
+ else:
+ w = wbk[pos:pos+ln]
+ pos = pos + ln
+ pos += 4*rt
+ pos += sz
+ return w, pos - save
+def i2b(n):
+ w=''
+ while n>0:
+ w=str(n%2)+w
+ n/=2
+ if len(w)<64:
+ return '0'*(64-len(w))+w
+ return w
+def b2i(w):
+ ans = 0
+ p2 = 1
+ for i in w[::-1]:
+ ans+=p2*int(i)
+ p2*=2
+ return ans
+def get_label(n):
+ if n<26:
+ return chr(n%26+65)
+ return chr(n/26-1+65)+chr(n%26+65)
+def floating(n):
+ w = i2b(n)
+ sign = (-1)**int(w[0])
+ e = b2i(w[1:12])
+ f = b2i(w[12:])/2.0**52
+ if e==2047 and f!=0:
+ return 'NaN'
+ if e==2047 and f==0 and sign==-1:
+ return '-INF'
+ if e==2047 and f==0 and sign==1:
+ return 'INF'
+ if e==0:
+ return '0.0'
+ return str(sign * 2**(e-1023)*(1+f))
+def read_cell_address(w):
+ r=str(1+integer(w[:2]))
+ i=(integer(w[2:]))&0x00FF
+ c =get_label(i)
+ return c + r
+def read_cellrange_address(w):
+ r1= str(1+integer(w[:2]))
+ r2= str(1+integer(w[2:4]))
+ i= (integer(w[4:6])) & 0x00FF
+ c1= get_label(i)
+ i= (integer(w[6:8])) & 0x00FF
+ c2= get_label(i)
+ return c1+r1+ ':' +c2+r2
+def skip_attr(s, pos): # tAttr token: this token has many different tokens
+ t = integer(s[pos+1]) # tAttrChoose token ,# IF control, choose, skip etc
+ if t == 0x04:
+ nc=integer(s[pos+2:pos+4])
+ return nc*2 + 6 ,t
+ return 4, t
+
+def read_additional(s, pos, tid):
+ ans=''
+ np=pos
+ if tid == 0x20 or tid == 0x40 or tid == 0x60:
+ ans+='{'
+ nc= integer(s[pos])+1
+ nr= integer(s[pos+1:pos+3])+1
+ np+=3
+ for i in range(0, nr):
+ for j in range(0, nc):
+ if integer(s[np])==0x00: # empty
+ ans += ','
+ np += 9
+ elif integer(s[np])==0x01: # float
+ ans += str(floating(hexa(s[np+1:np+9])))+','
+ np+=9
+ elif integer(s[np])==0x02: # string
+ st,bytes = read_string(s, np+1, 2)
+ ans+= '"' + st + '"' + ','
+ np+=1+bytes
+ elif integer(s[np])==0x04: # boolean
+ if integer(s[np+1])==1:
+ ans+='TRUE,'
+ else:
+ ans+='FALSE,'
+ np+=9
+ elif integer(s[np])==0x10: # error value
+ ans+=err_value[integer(s[np+1])]+','
+ np+=9
+ else:
+ pass
+ ans=ans[:len(ans)-1]+';'
+ ans=ans[:len(ans)-1]+'}'
+ return ans, np-pos
+ return '', 0
+
+
+global fn_list
+fn_list=['']*368
+fp=open(activity.get_bundle_path()+'/interoperability/xls/function.txt','r')
+for i in range(0, 249):
+ s = fp.readline()
+ l=s.split()
+ if l[2]==l[3]:
+ arg = int(l[2])
+ else:
+ arg = -1
+ fn_list[int(l[0])] = l[1], arg
+
+token_list=['','','','+','-','*','/','^','&','<','<=','=','>=','>']
+token_list+=['<>', ' ', ',' ,':', 'u-', 'u+','%', '()', '']
+def read_formula(s):
+ rpn=[] # rpn array
+ add_list=[]
+ size=integer(s[:2])
+ pos = 2
+ while pos != 2+size:
+ tid = integer(s[pos])
+ if tid>=0x00 and tid<=0x02: return 'UNKNOWN'
+
+ elif tid>=0x03 and tid<=0x16:
+ rpn+=[token_list[tid]]
+ pos+=1
+ elif tid==0x17: # string
+ st, bytes = read_string(s, pos+1, 1)
+ pos=pos+1+bytes
+ rpn+=['"'+st+'"']
+ elif tid==0x1C: # error value
+ er=err_value[integer(s[pos+1])]
+ rpn+=[er]
+ pos+=2
+ elif tid==0x1D: # bool
+ nt=integer(s[pos+1])
+ if nt==0: rpn+=['FALSE']
+ else: rpn+=['TRUE']
+ pos+=2
+ elif tid==0x1E: # integer
+ rpn+=[str(integer(s[pos+1:pos+3]))]
+ pos+=3
+ elif tid==0x1F: # float
+ fv = floating(hexa(s[pos+1:pos+9]))
+ pos+=9
+ rpn+=[str(fv)]
+ elif tid==0x21 or tid==0x41 or tid==0x61: # const argc function name
+ ( fn, argc )= fn_list[integer(s[pos+1:pos+3])]
+ rpn+=[(fn, argc)]
+ pos+=3
+ elif tid==0x22 or tid==0x42 or tid==0x62: # variable argc function name
+ try:
+ fn, argc = fn_list[integer(s[pos+2:pos+4])]
+ except:
+ return 'UNKNOWN'
+ argc=integer(s[pos+1])
+ rpn+=[(fn, argc)]
+ pos+=4
+ elif tid == 0x24 or tid==0x44 or tid==0x64: # tRef
+ rpn+=[read_cell_address(s[pos+1:pos+5])]
+ pos+=5
+ elif tid == 0x25 or tid==0x45 or tid==0x65: # tArea
+ rpn+=[read_cellrange_address(s[pos+1:pos+9])]
+ pos+=9
+ elif tid == 0x20 or tid == 0x40 or tid == 0x60: # tArray
+ add_list+=[ (len(rpn), tid) ]
+ pos+=8
+ elif tid == 0x26 or tid == 0x46 or tid == 0x66:
+ pos+=7
+ elif tid == 0x19:
+ bytes, t = skip_attr(s, pos)
+ pos += bytes
+ if t==0x10:
+ rpn+=[('SUM', 1)] # tAttrSum replaces the tFuncVar token here
+ else:
+ return 'UNKNOWN' # has to take care of some other tokens too
+
+ for i in range(0, len(add_list)): # additional data
+ index, tid = add_list[i]
+ dt, bytes = read_additional(s, pos, tid)
+ pos+=bytes
+ rpn.insert(index, dt)
+
+ l=len(rpn)
+ stk=[]
+ for i in range(0,l): # converting RPN to formula using stack
+ if rpn[i] in token_list[:18]:
+ t2=stk.pop()
+ t1=stk.pop()
+ stk+=[t1+rpn[i]+t2]
+ elif rpn[i]=='u+' or rpn[i]=='u-':
+ t1=stk.pop()
+ ch=rpn[i]
+ stk+=[ch[1]+t1]
+ elif rpn[i]=='%':
+ t1=stk.pop()
+ stk+=[t1+'%']
+ elif rpn[i]=='()':
+ t1=stk.pop()
+ stk+=['('+t1+')']
+ elif type(rpn[i])==tuple:
+ fname, argc = rpn[i]
+ fnstr=')'
+ for j in range(0, argc):
+ fnstr=',' + stk.pop() + fnstr
+ if argc != 0:
+ fnstr=fnstr[1:]
+ fnstr= fname+'('+fnstr
+ stk+=[fnstr]
+ else:
+ stk+=[rpn[i]]
+ return stk[0]
+
+
+
diff --git a/interoperability/xls/function.pyo b/interoperability/xls/function.pyo
new file mode 100644
index 0000000..8015417
--- /dev/null
+++ b/interoperability/xls/function.pyo
Binary files differ
diff --git a/interoperability/xls/function.txt b/interoperability/xls/function.txt
new file mode 100644
index 0000000..cd21337
--- /dev/null
+++ b/interoperability/xls/function.txt
@@ -0,0 +1,249 @@
+0 COUNT 0 30
+27 ROUND 2 2
+1 IF 2 3
+28 LOOKUP 2 3
+2 ISNA 1 1
+29 INDEX 2 4
+3 ISERROR 1 1
+30 REPT 2 2
+4 SUM 0 30
+31 MID 3 3
+5 AVERAGE 1 30
+32 LEN 1 1
+6 MIN 1 30
+33 VALUE 1 1
+7 MAX 1 30
+34 TRUE 0 0
+8 ROW 0 1
+35 FALSE 0 0
+9 COLUMN 0 1
+36 AND 1 30
+10 NA 0 0
+37 OR 1 30
+11 NPV 2 30
+38 NOT 1 1
+12 STDEV 1 30
+39 MOD 2 2
+13 DOLLAR 1 2
+40 DCOUNT 3 3
+14 FIXED 2 2
+41 DSUM 3 3
+15 SIN 1 1
+42 DAVERAGE 3 3
+16 COS 1 1
+43 DMIN 3 3
+17 TAN 1 1
+44 DMAX 3 3
+18 ATAN 1 1
+45 DSTDEV 3 3
+19 PI 0 0
+46 VAR 1 30
+20 SQRT 1 1
+47 DVAR 3 3
+21 EXP 1 1
+48 TEXT 2 2
+22 LN 1 1
+49 LINEST 1 2
+23 LOG10 1 1
+50 TREND 1 3
+24 ABS 1 1
+51 LOGEST 1 2
+25 INT 1 1
+52 GROWTH 1 3
+26 SIGN 1 1
+56 PV 3 5
+57 FV 3 5
+116 RIGHT 1 2
+58 NPER 3 5
+117 EXACT 2 2
+59 PMT 3 5
+118 TRIM 1 1
+60 RATE 3 6
+119 REPLACE 4 4
+61 MIRR 3 3
+120 SUBSTITUTE 3 4
+62 IRR 1 2
+121 CODE 1 1
+63 RAND 0 0
+124 FIND 2 3
+64 MATCH 2 3
+125 CELL 1 2
+65 DATE 3 3
+126 ISERR 1 1
+66 TIME 3 3
+127 ISTEXT 1 1
+67 DAY 1 1
+128 ISNUMBER 1 1
+68 MONTH 1 1
+129 ISBLANK 1 1
+69 YEAR 1 1
+130 T 1 1
+70 WEEKDAY 1 1
+131 N 1 1
+71 HOUR 1 1
+140 DATEVALUE 1 1
+72 MINUTE 1 1
+141 TIMEVALUE 1 1
+73 SECOND 1 1
+142 SLN 3 3
+74 NOW 0 0
+143 SYD 4 4
+75 AREAS 1 1
+144 DDB 4 5
+76 ROWS 1 1
+148 INDIRECT 1 2
+77 COLUMNS 1 1
+162 CLEAN 1 1
+78 OFFSET 3 5
+163 MDETERM 1 1
+82 SEARCH 2 3
+164 MINVERSE 1 1
+83 TRANSPOSE 1 1
+165 MMULT 2 2
+86 TYPE 1 1
+167 IPMT 4 6
+97 ATAN2 2 2
+168 PPMT 4 6
+98 ASIN 1 1
+169 COUNTA 0 30
+99 ACOS 1 1
+183 PRODUCT 0 30
+100 CHOOSE 2 30
+184 FACT 1 1
+101 HLOOKUP 3 3
+189 DPRODUCT 3 3
+102 VLOOKUP 3 3
+190 ISNONTEXT 1 1
+105 ISREF 1 1
+193 STDEVP 1 30
+109 LOG 1 2
+194 VARP 1 30
+111 CHAR 1 1
+195 DSTDEVP 3 3
+112 LOWER 1 1
+196 DVARP 3 3
+113 UPPER 1 1
+197 TRUNC 1 1
+114 PROPER 1 1
+198 ISLOGICAL 1 1
+115 LEFT 1 2
+199 DCOUNTA 3 3
+49 LINEST 1 4
+215 JIS 1 1
+50 TREND 1 4
+219 ADDRESS 2 5
+51 LOGEST 1 4
+220 DAYS360 2 2
+52 GROWTH 1 4
+221 TODAY 0 0
+197 TRUNC 1 2
+222 VDB 5 7
+204 YEN 1 2
+227 MEDIAN 1 30
+205 FINDB 2 3
+228 SUMPRODUCT 1 30
+206 SEARCHB 2 3
+229 SINH 1 1
+207 REPLACEB 4 4
+230 COSH 1 1
+208 LEFTB 1 2
+231 TANH 1 1
+209 RIGHTB 1 2
+232 ASINH 1 1
+210 MIDB 3 3
+233 ACOSH 1 1
+211 LENB 1 1
+234 ATANH 1 1
+212 ROUNDUP 2 2
+235 DGET 3 3
+213 ROUNDDOWN 2 2
+244 INFO 1 1
+214 ASC 1 1
+14 FIXED 2 3
+298 ODD 1 1
+204 USDOLLAR 1 2
+299 PERMUT 2 2
+215 DBCS 1 1
+300 POISSON 3 3
+216 RANK 2 3
+301 TDIST 3 3
+247 DB 4 5
+302 WEIBULL 4 4
+252 FREQUENCY 2 2
+303 SUMXMY2 2 2
+261 ERROR.TYPE 1 1
+304 SUMX2MY2 2 2
+269 AVEDEV 1 30
+305 SUMX2PY2 2 2
+270 BETADIST 3 5
+306 CHITEST 2 2
+271 GAMMALN 1 1
+307 CORREL 2 2
+272 BETAINV 3 5
+308 COVAR 2 2
+273 BINOMDIST 4 4
+309 FORECAST 3 3
+274 CHIDIST 2 2
+310 FTEST 2 2
+275 CHIINV 2 2
+311 INTERCEPT 2 2
+276 COMBIN 2 2
+312 PEARSON 2 2
+277 CONFIDENCE 3 3
+313 RSQ 2 2
+278 CRITBINOM 3 3
+314 STEYX 2 2
+279 EVEN 1 1
+315 SLOPE 2 2
+280 EXPONDIST 3 3
+316 TTEST 4 4
+281 FDIST 3 3
+317 PROB 3 4
+282 FINV 3 3
+318 DEVSQ 1 30
+283 FISHER 1 1
+319 GEOMEAN 1 30
+284 FISHERINV 1 1
+320 HARMEAN 1 30
+285 FLOOR 2 2
+321 SUMSQ 0 30
+286 GAMMADIST 4 4
+322 KURT 1 30
+287 GAMMAINV 3 3
+323 SKEW 1 30
+288 CEILING 2 2
+324 ZTEST 2 3
+289 HYPGEOMDIST 4 4
+325 LARGE 2 2
+290 LOGNORMDIST 3 3
+326 SMALL 2 2
+291 LOGINV 3 3
+327 QUARTILE 2 2
+292 NEGBINOMDIST 3 3
+328 PERCENTILE 2 2
+293 NORMDIST 4 4
+329 PERCENTRANK 2 3
+294 NORMSDIST 1 1
+330 MODE 1 30
+295 NORMINV 3 3
+331 TRIMMEAN 2 2
+296 NORMSINV 1 1
+332 TINV 2 2
+297 STANDARDIZE 3 3
+70 WEEKDAY 1 2
+345 SUMIF 2 3
+101 HLOOKUP 3 4
+346 COUNTIF 2 2
+102 VLOOKUP 3 4
+347 COUNTBLANK 1 1
+220 DAYS360 2 3
+350 ISPMT 4 4
+336 CONCATENATE 0 30
+351 DATEDIF 3 3
+337 POWER 2 2
+352 DATESTRING 1 1
+342 RADIANS 1 1
+353 NUMBERSTRING 2 2
+343 DEGREES 1 1
+354 ROMAN 1 2
+344 SUBTOTAL 2 30 \ No newline at end of file
diff --git a/interoperability/xls/workbook.py b/interoperability/xls/workbook.py
new file mode 100644
index 0000000..4398989
--- /dev/null
+++ b/interoperability/xls/workbook.py
@@ -0,0 +1,432 @@
+# Ability to read single sheet Excel .xls files in SocialCalc added. Developed by Mahesh Chand Sharma from SEETA (http://seeta.in) with pointers from Vijit Singh,
+# Software Engineer at SEETA (http://seeta.in) under the guidance of Manusheel Gupta.
+# For getting involved in the development of SocialCalc on Sugar, or on any questions related to it, please e-mail at socialcalc<dot>sugar<at>seeta<dot>in.
+# For posting a feature request/bug, please use http://testtrack.seeta.in.
+# File Author - Mahesh Chand Sharma
+
+from convert_to_scalcstring import workbook_data_to_scalc_string
+from compound import return_wbk, integer, hexa
+from function import read_formula
+global err_value
+
+err_value = ['']*(0x2A +1)
+err_value[0x00] = '#NULL!'
+err_value[0x07] = '#DIV/0!'
+err_value[0x0F] = '#VALUE'
+err_value[0x17] = '#REF!'
+err_value[0x1D] = '#NAME?'
+err_value[0x24] = '#NUM!'
+err_value[0x2A] = '#N/A!'
+
+def next_record_info():
+ global ptr
+ identity = hexa(wbk[ptr : ptr+2])
+ off = ptr + 4
+ size = integer(wbk[ptr+2 : ptr+4])
+ ptr = ptr +4 +size
+ return (identity, off, size)
+def i2b(n):
+ s=''
+ while n>0:
+ s=str(n%2)+s
+ n/=2
+ if len(s)<64:
+ return '0'*(64-len(s))+s
+ return s
+def b2i(s):
+ ans = 0
+ p2 = 1
+ for i in s[::-1]:
+ ans+=p2*int(i)
+ p2*=2
+ return ans
+def read_string(pos, len_size):
+ save=pos
+ ln=integer(wbk[pos:pos+len_size])
+ pos+=len_size
+ flag=integer(wbk[pos:pos+1])
+ pos+=1
+ rt = 0
+ sz = 0
+ if flag&8==8:
+ rt = integer(wbk[pos : pos+2])
+ pos+=2
+ if flag&4==4:
+ sz = integer(wbk[pos : pos+4])
+ pos+=4
+ if flag&1==1:
+ s = wbk[pos:pos+2*ln:2]
+ pos = pos+2*ln
+ else:
+ s = wbk[pos:pos+ln]
+ pos = pos + ln
+ pos += 4*rt
+ pos += sz
+ return s, pos-save
+def read_index_record(off, size):
+ rf = integer(wbk[off+4:off+8])
+ rl = integer(wbk[off+8:off+12])
+ l=[]
+ for i in range(0, (size - 16) / 4):
+ l.append(integer(wbk[off+16+4*i:off+16+4*(i+1)]))
+ return rf, rl, l
+
+def read_dimension_record(off, size):
+ rf = integer(wbk[off:off+4])
+ rl = integer(wbk[off+4:off+8])
+ cf = integer(wbk[off+8:off+10])
+ cl = integer(wbk[off+10:off+12])
+ return rf,rl,cf,cl
+
+def read_row_record(off, size):
+ r = integer(wbk[off:off+2])
+ c1 = integer(wbk[off+2:off+4])
+ c2 = integer(wbk[off+4:off+6])
+ return r, c1, c2
+
+def read_dbcell_record(off, size):
+ l=[]
+ for i in range(0, (size-4)/2):
+ l.append(integer(wbk[off+4+2*i : off+4+2*i+2]))
+ return l
+
+def read_sst_record(off, size):
+ nm = integer(wbk[off+4:off+8])
+ off += 8
+ bytes = 0
+ l=[]
+ s=''
+ for i in range(0, nm):
+ (s, bytes) = read_string(off, 2)
+ off += bytes
+ l.append(s)
+ return l
+
+def read_blank_record(off, size):
+ r = integer(wbk[off : off+2])
+ c = integer(wbk[off+2 : off+4])
+ return r, c, '', 's'
+
+def read_labelsst_record(off, size):
+ r = integer(wbk[off : off+2])
+ c = integer(wbk[off+2 : off+4])
+ j = integer(wbk[off+4 : off+6])
+ fs=xf[j]
+ i = integer(wbk[off+6 : off+10])
+ return r, c, sst[i], 's', fs
+
+def read_label_record(off, size):
+ r = integer(wbk[off : off+2])
+ c = integer(wbk[off+2 : off+4])
+ i = integer(wbk[off+4 : off+6])
+ fs=xf[i]
+ s, bytes = read_string(off+6, 2)
+ return r, c, s, 's', fs
+
+def read_float_record(off, size):
+ r = integer(wbk[off : off+2])
+ c = integer(wbk[off+2 : off+4])
+ i = integer(wbk[off+4 : off+6])
+ fs=xf[i]
+ fv = floating(hexa(wbk[off+6:off+14]))
+ return r, c, fv, 'f', fs
+def read_rk_value(val):
+ change = val & 0x00000001
+ tp = val & 0x00000002
+ val = val & 0xfffffffc
+ if tp==0:
+ val= val*2**32
+ if change == 1: return float(floating(val))/100.0, 'f'
+ else: return float(floating(val)), 'f'
+ if tp==2:
+ val=val>>2
+ if val > 536870911: val = (2**30-val)*(-1)
+ if change==1:
+ return val/100, 'i'
+ else:
+ return val, 'i'
+
+def read_rk_record(off, size):
+ r = integer(wbk[off : off+2])
+ c = integer(wbk[off+2 : off+4])
+ i = integer(wbk[off+4 : off+6])
+ fs=xf[i]
+ rk_val = hexa(wbk[off+6 : off+10])
+ val, typ = read_rk_value(rk_val)
+ if int(val) == val:
+ val = int(val)
+ typ = 'i'
+ return r, c, str(val), typ, fs
+
+
+def read_boolerr_record(off, size):
+ r = integer(wbk[off : off+2])
+ c = integer(wbk[off+2 : off+4])
+ i = integer(wbk[off+4 : off+6])
+ fs=xf[i]
+ typ = integer(wbk[off+7 : off+8])
+ val = integer(wbk[off+6 : off+7])
+ if typ == 0: # 0 for boolean
+ return r, c, bool(val), 'b', fs
+ else:
+ return r, c, err_value[val], 'e', fs
+def read_mulrk_record(off, size):
+ r = integer(wbk[off : off+2])
+ fc = integer(wbk[off+2 : off+4])
+ nc = (size - 6) / 6
+ l = []
+ for i in range(0, nc):
+ j = integer(wbk[off+4+6*i : off+4+6*i+2])
+ fs=xf[j]
+ rk_val = integer(wbk[off + 4+6*i+2 : off+ 4+6*i+2+4])
+ val, typ = read_rk_value(rk_val)
+ if int(val) == val:
+ val = int(val)
+ typ = 'i'
+ c = fc + i
+ l.append( (r, c, val, typ, fs) )
+ return l
+
+
+def floating(n):
+ s = i2b(n)
+ sign = (-1)**int(s[0])
+ e = b2i(s[1:12])
+ f = b2i(s[12:])/2.0**52
+ if e==2047 and f!=0:
+ return 'NaN'
+ if e==2047 and f==0 and sign==-1:
+ return '-INF'
+ if e==2047 and f==0 and sign==1:
+ return 'INF'
+ if e==0:
+ return '0.0'
+ return str(sign * 2**(e-1023)*(1+f))
+def calc_formula_result(off, size):
+ i = integer(wbk[off : off+1])
+ if i == 0x01:
+ return bool(integer(wbk[off+2 : off+3])), 'b'
+ if i == 0x02:
+ ec = integer(wbk[off+2 : off+3])
+ return err_value[ec], 'e'
+ if i == 0x03:
+ return '', 's'
+ else:
+ return floating( integer(wbk[off : off+8]) ), 'f'
+
+def read_formula_record(off, size):
+ r = integer(wbk[off : off+2])
+ c = integer(wbk[off+2 : off+4])
+ i = integer(wbk[off+4 : off+6])
+ fs=xf[i]
+ val, typ = calc_formula_result(off+6, 8)
+ formula = read_formula(wbk[off+20 : off + size])
+ return r, c, val, fs, typ, formula
+
+def read_font_record(off, size):
+ h = integer(wbk[off : off+2])/20
+ i=integer(wbk[off+2 : off+4])
+ bold = ((i & 0x0001)==1)
+ italic = ((i & 0x0002)==2)
+ underlined = ((i & 0x0004)==4)
+ return int(bold), int(italic), int(underlined), h
+
+
+def read_xf_record(off, size):
+ ans=''
+ i=integer(wbk[off : off+2])
+ (b, it, u, h) = fonts[i]
+ ans+=str(b)
+ ans+=str(it)
+ ans+=str(u)
+ i=integer(wbk[off+6 : off+7])
+ n = i & 0x07
+ if n==2:
+ ans+='10' # center
+ elif n==3:
+ ans+='11' # right
+ else:
+ ans+='01' #left
+ n = (i & 0x70)/16
+ if n==1:
+ ans+='10' #center
+ elif n==2:
+ ans+='11' # bottom
+ else:
+ ans+='01' # top
+ n = (i & 0x08)/8
+ ans+=str(n) # 1 for word wrap
+ return ans, h
+
+def read_defcol_record(off, size):
+ return integer(wbk[off:off+2])
+
+def read_colinfo_record(off, size):
+ cf = integer(wbk[off : off+2])
+ cl = integer(wbk[off+2 : off+4])
+ w = integer(wbk[off+4 : off+6])/256 + 1
+ return cf, cl, w
+
+def read_standardwidth_record(off, size):
+ return integer(wbk[off:off+2])/16 + 1
+
+def bin2data(s):
+ global wbk, ptr, fonts, xf
+ wbk = return_wbk(s)
+ ptr=0
+ if wbk == 'file not in correct format':
+ return wbk
+
+ # reading the workbook global substream
+ (f, off, size) = next_record_info()# BOF record
+#####################################################
+ while f != 0x0031: # reaching to FONT Records
+ (f, off, size) = next_record_info()
+ fonts=[]
+ while f == 0x0031: # reading font records
+ tpl=read_font_record(off, size)
+ fonts.append(tpl)
+ if len(fonts)==4: # since font with index 4 has been ommited
+ fonts.append((0, 0, 0, 0)) # by excel :)
+ (f, off, size) = next_record_info()
+
+ while f != 0x00E0: # reaching to XF record
+ (f, off, size) = next_record_info()
+ xf=[]
+ while f == 0x00E0: # reading XF records
+ fs = read_xf_record(off, size) # fn is formatting no.
+ xf.append(fs)
+ (f, off, size) = next_record_info()
+#####################################################
+ while f != 0x0085: #reaching to SHEET Records
+ (f, off, size) = next_record_info()
+
+ sheets = [] # contains the info of all the worksheets
+ while f == 0x0085: #reading the SHEET records
+ record = wbk[off : off+size]
+
+ pos = integer(record[:4])
+ sheet_type = integer(record[5:6]);
+ (name, bytes) = read_string(off + 6, 1)
+ if sheet_type==0: # sheettype 0 for workssheet
+ sheets.append((pos, sheet_type, name))
+ (f, off, size) = next_record_info()
+ #building the SST shared string table
+ while f != 0x00FC: #reaching to SST record
+ (f, off, size) = next_record_info()
+ global sst
+ sst = [] # list of used strings
+ sst = read_sst_record(off, size)
+ workbook_data=[]
+ workbook_col_widths=[]
+ for sheet in sheets:
+ ptr = sheet[0] # offset of 1st worksheet
+ sheet_name = sheet[2]
+
+ next_record_info() # skipping the BOF record
+ (f, off, size) = next_record_info()
+ if f == 0x020B: # INDEX record
+ (rf, rl, dbcell_posns) = read_index_record(off, size)
+###################################################
+ colinfo=[]
+ def_width = 0
+ standard_width = 0
+ while f != 0x0200: #reaching to DIMENSION record
+ if f==0x0055: #reading DEFCOLWIDTH
+ def_width = read_defcol_record(off, size)
+ if f==0x007D: #reading COLINFO record
+ cnf = read_colinfo_record(off, size)
+ colinfo.append( cnf )
+ (f, off, size) = next_record_info()
+#####################################################
+ rf,rl,cf,cl = read_dimension_record(off, size)
+ if (rl-rf)%32==0: row_block_count = (rl-rf)/32
+ else: row_block_count = int((rl-rf)/32)+1
+
+ if row_block_count == 0: # sheet is empty
+ continue
+
+ #reading the data now
+ sheet_data = [[()]*cl]*rl # empty database
+ for i in range(0, row_block_count):
+ (f, off, size) = next_record_info()
+ while f == 0x0208:
+ (f, off, size) = next_record_info() # skipping the ROW record
+
+ while f != 0x00D7: # f==0x00D7 for DBCELL record
+ if f == 0x0205:
+ x, y, val, typ, fs = read_boolerr_record(off, size)
+ elif f == 0x0204:
+ x, y, val, typ, fs = read_label_record(off, size)
+ elif f == 0x00FD:
+ x, y, val, typ, fs = read_labelsst_record(off, size)
+ elif f == 0x0203:
+ x, y, val, typ, fs = read_float_record(off, size)
+
+ elif f == 0x027E:
+ x, y, val, typ, fs = read_rk_record(off, size)
+
+ elif f == 0x0006: # formula record
+ x, y, val, fs, typ, formula= read_formula_record(off, size)
+ buf = list(sheet_data[x])
+ buf[y] = (val, 'for', fs, typ, formula)
+ sheet_data[x] = buf
+ (f, off, size) = next_record_info()
+ continue
+ elif f == 0x00BD:
+ mul_cell_data = read_mulrk_record(off, size) # list of tuples
+ for tple in mul_cell_data:
+ x, y, val, typ, fs = tple
+ buf = list(sheet_data[x])
+ buf[y] = (val, typ, fs)
+ sheet_data[x] = buf
+ (f, off, size) = next_record_info()
+ continue
+ else:
+ (f, off, size) = next_record_info()
+ continue
+
+ buf = list(sheet_data[x])
+ buf[y] = (val, typ, fs)
+ sheet_data[x] = buf
+ (f, off, size) = next_record_info()
+
+ workbook_data.append(sheet_data)
+#########################################################
+ while f != 0x000A: # 000A for EOF record
+ if f==0x0099: # standardwidth record
+ standard_width = read_standardwidth_record(off, size)
+ (f, off, size) = next_record_info()
+
+ col_widths = [0]*cl
+ for tpl in colinfo:
+ for j in range(tpl[0], tpl[1]+1):
+ col_widths[j] = tpl[2]
+ if standard_width!=0:
+ default = standard_width
+ else:
+ default = def_width
+ for j in range(0, cl):
+ if col_widths[j] == 0:
+ col_widths[j]=default
+
+ workbook_col_widths.append(col_widths)
+###########################################################
+ return workbook_data_to_scalc_string(workbook_data, workbook_col_widths,0)
+
+
+
+#f=open('test.xls', 'rb')
+#s=f.read()
+#workbook_data = bin2data(s)
+############### END OF CODE #############################
+# NOW THE WORKBOOK_DATA CONTAINS THE DATA OF ALL THE SHEETS
+# IT IS A 3D LIST OF DATA (ROW*COL*SHEET) and each cell has two
+#fields (value, type)
+# WE CAN CHECK IT-
+#for sheet_data in workbook_data:
+# for row_data in sheet_data:
+# print row_data
+# print '\n\n'
+
+# NOW THIS DATA CAN BE USED TO LOAD TO THE SOCIALCALC
diff --git a/interoperability/xls/workbook.pyo b/interoperability/xls/workbook.pyo
new file mode 100644
index 0000000..a0a0d50
--- /dev/null
+++ b/interoperability/xls/workbook.pyo
Binary files differ
diff --git a/locale/af/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo b/locale/af/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
new file mode 100644
index 0000000..a7c9503
--- /dev/null
+++ b/locale/af/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
Binary files differ
diff --git a/locale/ar/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo b/locale/ar/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
new file mode 100644
index 0000000..3d54ae1
--- /dev/null
+++ b/locale/ar/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
Binary files differ
diff --git a/locale/de/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo b/locale/de/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
new file mode 100644
index 0000000..c82ebf6
--- /dev/null
+++ b/locale/de/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
Binary files differ
diff --git a/locale/es/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo b/locale/es/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
new file mode 100644
index 0000000..e6a9317
--- /dev/null
+++ b/locale/es/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
Binary files differ
diff --git a/locale/es/activity.linfo b/locale/es/activity.linfo
new file mode 100644
index 0000000..87a4542
--- /dev/null
+++ b/locale/es/activity.linfo
@@ -0,0 +1,2 @@
+[Activity]
+name = SocialCalc
diff --git a/locale/fr/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo b/locale/fr/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
new file mode 100644
index 0000000..1420cb5
--- /dev/null
+++ b/locale/fr/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
Binary files differ
diff --git a/locale/hi/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo b/locale/hi/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
new file mode 100644
index 0000000..1a1a7f0
--- /dev/null
+++ b/locale/hi/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
Binary files differ
diff --git a/locale/hi/activity.linfo b/locale/hi/activity.linfo
new file mode 100644
index 0000000..e05b65c
--- /dev/null
+++ b/locale/hi/activity.linfo
@@ -0,0 +1,2 @@
+[Activity]
+name = SocialCalcActivity
diff --git a/locale/ja/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo b/locale/ja/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
new file mode 100644
index 0000000..915ee94
--- /dev/null
+++ b/locale/ja/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
Binary files differ
diff --git a/locale/pt/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo b/locale/pt/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
new file mode 100644
index 0000000..434a36f
--- /dev/null
+++ b/locale/pt/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
Binary files differ
diff --git a/locale/ru/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo b/locale/ru/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
new file mode 100644
index 0000000..9bec957
--- /dev/null
+++ b/locale/ru/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
Binary files differ
diff --git a/locale/zh_CN/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo b/locale/zh_CN/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
new file mode 100644
index 0000000..e43f67b
--- /dev/null
+++ b/locale/zh_CN/LC_MESSAGES/com.socialtext.SocialCalcActivity.mo
Binary files differ
diff --git a/localized_strings_file.py b/localized_strings_file.py
new file mode 100644
index 0000000..c1ec996
--- /dev/null
+++ b/localized_strings_file.py
@@ -0,0 +1,402 @@
+# Localization infrastructure developed by Vijit Singh under the guidance of Manusheel Gupta, with pointers from Dan Bricklin.
+# For getting involved in the development of SocialCalc on Sugar, or on any questions related to it, please e-mail at socialcalc<dot>sugar<at>seeta<dot>in.
+# For posting a feature request/bug, please use http://testtrack.seeta.in.
+# File author - Vijit Singh
+
+### file to contain the localized strings
+# -*- coding: utf-8 -*-
+from gettext import gettext as _
+
+localized_strings={}
+
+def add_localized_strings():
+
+ #localized_strings['textdatadefaulttype']=_("t")
+ localized_strings['s_BrowserNotSupported']=_("Browser not supported.")
+ localized_strings['s_InternalError']=_( "Internal SocialCalc error (probably an internal bug):")
+ localized_strings['s_pssUnknownColType']=_("Unknown col type item")
+ localized_strings['s_pssUnknownRowType']=_("Unknown row type item")
+ localized_strings['s_pssUnknownLineType']=_("Unknown line type")
+ localized_strings['s_cfspUnknownCellType']=_("Unknown cell type item")
+ localized_strings['s_escUnknownSheetCmd']=_("Unknown sheet command: ")
+ localized_strings['s_escUnknownSetCoordCmd']=_("Unknown set coord command: ")
+ localized_strings['s_escUnknownCmd']=_("Unknown command: ")
+ localized_strings['s_caccCircRef']=_("Circular reference to ")
+## localized_strings['defaultRowNameWidth']=_("30")
+## localized_strings['defaultCellIDPrefix']=_("cell_")
+## localized_strings['defaultCellLayout']=_("padding:2px 2px 1px 2px;vertical-align:top;")
+ localized_strings['defaultCellFontStyle']=_("normal normal")
+ localized_strings['defaultCellFontSize']=_("small")
+## localized_strings['defaultCellFontFamily']=_("Verdana,Arial,Helvetica,sans-serif")
+ localized_strings['s_rcMissingSheet']=_("Render Context must have a sheet object")
+## localized_strings['defaultLinkFormatString']=_('<span style="font-size:smaller;text-decoration:none !important;background-color:#66B;color:#FFF;">Link</span>')
+## localized_strings['defaultPageLinkFormatString']=_('<span style="font-size:smaller;text-decoration:none !important;background-color:#66B;color:#FFF;">Page</span>')
+## localized_strings['defaultFormatdt']=_('d-mmm-yyyy h:mm:ss')
+## localized_strings['defaultFormatd']=_('d-mmm-yyyy')
+## localized_strings['defaultFormatt']=_('[h]:mm:ss')
+ localized_strings['defaultDisplayTRUE']=_('TRUE')
+ localized_strings['defaultDisplayFALSE']=_('FALSE')
+## localized_strings['defaultImagePrefix']=_("images/sc-")
+## localized_strings['defaultTableEditorIDPrefix']=_("te_")
+ localized_strings['s_statusline_executing']=_("Executing...")
+ localized_strings['s_statusline_displaying']=_("Displaying...")
+ localized_strings['s_statusline_ordering']=_("Ordering...")
+ localized_strings['s_statusline_calculating']=_("Calculating...")
+ localized_strings['s_statusline_calculatingls']=_("Calculating... Loading Sheet...")
+ localized_strings['s_statusline_doingserverfunc']=_("doing server function ")
+ localized_strings['s_statusline_incell']=_(" in cell ")
+ localized_strings['s_statusline_calcstart']=_("Calculation start...")
+ localized_strings['s_statusline_sum']=_("SUM")
+## localized_strings['s_statusline_recalcneeded']=_('<span style="color:#999;">(Recalc needed)</span>')
+## localized_strings['s_statusline_circref']=_('<span style="color:red;">Circular reference: ')
+ localized_strings['s_inputboxdisplaymultilinetext']=_("[Multi-line text: Click icon on right to edit]")
+ localized_strings['ietUnknownFunction']=_("Unknown function ")
+ localized_strings['s_panesliderTooltiph']=_("Drag to lock pane vertically")
+ localized_strings['s_panesliderTooltipv']=_("Drag to lock pane horizontally")
+ localized_strings['s_loc_align_center']=_("Align Center")
+ localized_strings['s_loc_align_left']=_("Align Left")
+ localized_strings['s_loc_align_right']=_("Align Right")
+ localized_strings['s_loc_alignment']=_("Alignment")
+ localized_strings['s_loc_audit']=_("Audit")
+## localized_strings['s_loc_audit_trail_thilocalized_strings['s_session']=_("Audit Trail This Session")
+ localized_strings['s_loc_auto']=_("Auto")
+ localized_strings['s_loc_auto_sum']=_("Auto Sum")
+ localized_strings['s_loc_auto_wX_commas']=_("Auto w/ commas")
+ localized_strings['s_loc_automatic']=_("Automatic")
+ localized_strings['s_loc_background']=_("Background")
+ localized_strings['s_loc_bold']=_("Bold")
+ localized_strings['s_loc_bold_XampX_italics']=_("Bold &amp; Italics")
+ localized_strings['s_loc_bold_italic']=_("Bold Italic")
+ localized_strings['s_loc_borders']=_("Borders")
+ localized_strings['s_loc_borders_off']=_("Borders Off")
+ localized_strings['s_loc_borders_on']=_("Borders On")
+ localized_strings['s_loc_bottom']=_("Bottom")
+ localized_strings['s_loc_bottom_border']=_("Bottom Border")
+ localized_strings['s_loc_cell_settings']=_("CELL SETTINGS")
+ localized_strings['s_loc_csv_format']=_("CSV format")
+ localized_strings['s_loc_cancel']=_("Cancel")
+ localized_strings['s_loc_category']=_("Category")
+ localized_strings['s_loc_center']=_("Center")
+ localized_strings['s_loc_clear']=_("Clear")
+ localized_strings['s_loc_clear_socialcalc_clipboard']=_("Clear SocialCalc Clipboard")
+ localized_strings['s_loc_clipboard']=_("Clipboard")
+ localized_strings['s_loc_color']=_("Color")
+ localized_strings['s_loc_column_']=_("Column ")
+ localized_strings['s_loc_comment']=_("Comment")
+ localized_strings['s_loc_copy']=_("Copy")
+ localized_strings['s_loc_custom']=_("Custom")
+ localized_strings['s_loc_cut']=_("Cut")
+ localized_strings['s_loc_default']=_("Default")
+ localized_strings['s_loc_default_alignment']=_("Default Alignment")
+ localized_strings['s_loc_default_column_width']=_("Default Column Width")
+ localized_strings['s_loc_default_font']=_("Default Font")
+ localized_strings['s_loc_default_format']=_("Default Format")
+ localized_strings['s_loc_default_padding']=_("Default Padding")
+ localized_strings['s_loc_delete']=_("Delete")
+ localized_strings['s_loc_delete_column']=_("Delete Column")
+ localized_strings['s_loc_delete_contents']=_("Delete Contents")
+ localized_strings['s_loc_delete_row']=_("Delete Row")
+ localized_strings['s_loc_description']=_("Description")
+ localized_strings['s_loc_display_clipboard_in']=_("Display Clipboard in")
+ localized_strings['s_loc_down']=_("Down")
+ localized_strings['s_loc_edit']=_("Edit")
+ localized_strings['s_loc_existing_names']=_("Existing Names")
+ localized_strings['s_loc_family']=_("Family")
+ localized_strings['s_loc_fill_down']=_("Fill Down")
+ localized_strings['s_loc_fill_right']=_("Fill Right")
+ localized_strings['s_loc_font']=_("Font")
+ localized_strings['s_loc_format']=_("Format")
+ localized_strings['s_loc_formula']=_("Formula")
+ localized_strings['s_loc_function_list']=_("Function List")
+ localized_strings['s_loc_functions']=_("Functions")
+ localized_strings['s_loc_grid']=_("Grid")
+ localized_strings['s_loc_hidden']=_("Hidden")
+ localized_strings['s_loc_horizontal']=_("Horizontal")
+ localized_strings['s_loc_insert_column']=_("Insert Column")
+ localized_strings['s_loc_insert_row']=_("Insert Row")
+ localized_strings['s_loc_italic']=_("Italic")
+ localized_strings['s_loc_last_sort']=_("Last Sort")
+ localized_strings['s_loc_left']=_("Left")
+ localized_strings['s_loc_left_border']=_("Left Border")
+ localized_strings['s_loc_link']=_("Link")
+ localized_strings['s_loc_link_input_box']=_("Link Input Box")
+ localized_strings['s_loc_list']=_("List")
+ localized_strings['s_loc_load_socialcalc_clipboard_with_this']=_("Load SocialCalc Clipboard With This")
+ localized_strings['s_loc_major_sort']=_("Major Sort")
+ localized_strings['s_loc_manual']=_("Manual")
+ localized_strings['s_loc_merge_cells']=_("Merge Cells")
+ localized_strings['s_loc_middle']=_("Middle")
+ localized_strings['s_loc_minor_sort']=_("Minor Sort")
+ localized_strings['s_loc_move_insert']=_("Move Insert")
+ localized_strings['s_loc_move_paste']=_("Move Paste")
+ localized_strings['s_loc_multiXline_input_box']=_("Multi-line Input Box")
+ localized_strings['s_loc_name']=_("Name")
+ localized_strings['s_loc_names']=_("Names")
+ localized_strings['s_loc_no_padding']=_("No padding")
+ localized_strings['s_loc_normal']=_("Normal")
+ localized_strings['s_loc_number']=_("Number")
+ localized_strings['s_loc_number_horizontal']=_("Number Horizontal")
+ localized_strings['s_loc_ok']=_("OK")
+ localized_strings['s_loc_padding']=_("Padding")
+ localized_strings['s_loc_page_name']=_("Page Name")
+ localized_strings['s_loc_paste']=_("Paste")
+ localized_strings['s_loc_paste_formats']=_("Paste Formats")
+ localized_strings['s_loc_plain_text']=_("Plain Text")
+ localized_strings['s_loc_recalc']=_("Recalc")
+ localized_strings['s_loc_recalculation']=_("Recalculation")
+ localized_strings['s_loc_redo']=_("Redo")
+ localized_strings['s_loc_right']=_("Right")
+ localized_strings['s_loc_right_border']=_("Right Border")
+ localized_strings['s_loc_sheet_settings']=_("SHEET SETTINGS")
+ localized_strings['s_loc_save']=_("Save")
+ localized_strings['s_loc_save_to']=_("Save to")
+ localized_strings['s_loc_set_cell_contents']=_("Set Cell Contents")
+ localized_strings['s_loc_set_cells_to_sort']=_("Set Cells To Sort")
+ localized_strings['s_loc_set_value_to']=_("Set Value To")
+ localized_strings['s_loc_set_to_link_format']=_("Set to Link format")
+ localized_strings['s_loc_setXclear_move_from']=_("Set/Clear Move From")
+ localized_strings['s_loc_show_cell_settings']=_("Show Cell Settings")
+ localized_strings['s_loc_show_sheet_settings']=_("Show Sheet Settings")
+ localized_strings['s_loc_show_in_new_browser_window']=_("Show in new browser window")
+ localized_strings['s_loc_size']=_("Size")
+ localized_strings['s_loc_socialcalcXsave_format']=_("SocialCalc-save format")
+ localized_strings['s_loc_sort']=_("Sort")
+ localized_strings['s_loc_sort_']=_("Sort ")
+ localized_strings['s_loc_sort_cells']=_("Sort Cells")
+ localized_strings['s_loc_swap_colors']=_("Swap Colors")
+ localized_strings['s_loc_tabXdelimited_format']=_("Tab-delimited format")
+ localized_strings['s_loc_text']=_("Text")
+ localized_strings['s_loc_text_horizontal']=_("Text Horizontal")
+ localized_strings['s_loc_this_is_aXbrXsample']=_("This is a<br>sample")
+ localized_strings['s_loc_top']=_("Top")
+ localized_strings['s_loc_top_border']=_("Top Border")
+ localized_strings['s_loc_undone_steps']=_("UNDONE STEPS")
+ localized_strings['s_loc_url']=_("URL")
+ localized_strings['s_loc_undo']=_("Undo")
+ localized_strings['s_loc_unmerge_cells']=_("Unmerge Cells")
+ localized_strings['s_loc_up']=_("Up")
+ localized_strings['s_loc_value']=_("Value")
+ localized_strings['s_loc_vertical']=_("Vertical")
+ localized_strings['s_loc_workspace']=_("Workspace")
+ localized_strings['s_loc_XnewX']=_("[New]")
+ localized_strings['s_loc_XnoneX']=_("[None]")
+ localized_strings['s_loc_Xselect_rangeX']=_("[select range]")
+## localized_strings['FormatNumber_separatorchar']=_(")") // the thousands separator character when formatting numbers for display
+## localized_strings['FormatNumber_decimalchar']=_(".") // the decimal separator character when formatting numbers for display
+## localized_strings['FormatNumber_defaultCurrency']=_("$") // the currency string used if none specified
+## localized_strings['s_FormatNumber_daynames']=_(["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"])
+## localized_strings['s_FormatNumber_daynames3']=_(["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"])
+## localized_strings['s_FormatNumber_monthnames']=_(["January", "February", "March", "April", "May", "June", "July", "August", "September","October", "November", "December"])
+## localized_strings['s_FormatNumber_monthnames3']=_(["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"])
+## localized_strings['s_FormatNumber_am']=_("AM")
+## localized_strings['s_FormatNumber_am1']=_("A")
+## localized_strings['s_FormatNumber_pm']=_("PM")
+## localized_strings['s_FormatNumber_pm1']=_("P")
+ localized_strings['s_parseerrexponent']=_("Improperly formed number exponent")
+ localized_strings['s_parseerrchar']=_("Unexpected character in formula")
+ localized_strings['s_parseerrstring']=_("Improperly formed string")
+ localized_strings['s_parseerrspecialvalue']=_("Improperly formed special value")
+ localized_strings['s_parseerrtwoops']=_("Error in formula (two operators inappropriately in a row)")
+ localized_strings['s_parseerrmissingopenparen']=_("Missing open parenthesis in list with comma(s). ")
+ localized_strings['s_parseerrcloseparennoopen']=_("Closing parenthesis without open parenthesis. ")
+ localized_strings['s_parseerrmissingcloseparen']=_("Missing close parenthesis. ")
+ localized_strings['s_parseerrmissingoperand']=_("Missing operand. ")
+ localized_strings['s_parseerrerrorinformula']=_("Error in formula.")
+ localized_strings['s_calcerrerrorvalueinformula']=_("Error value in formula")
+ localized_strings['s_parseerrerrorinformulabadval']=_("Error in formula resulting in bad value")
+ localized_strings['s_formularangeresult']=_("Formula results in range value:")
+ localized_strings['s_calcerrnumericnan']=_("Formula results in an bad numeric value")
+ localized_strings['s_calcerrnumericoverflow']=_("Numeric overflow")
+ localized_strings['s_sheetunavailable']=_("Sheet unavailable:") # when FindSheetInCache returns null
+ localized_strings['s_calcerrcellrefmissing']=_("Cell reference missing when expected.")
+ localized_strings['s_calcerrsheetnamemissing']=_("Sheet name missing when expected.")
+ localized_strings['s_circularnameref']=_("Circular name reference to name")
+ localized_strings['s_calcerrunknownname']=_("Unknown name")
+ localized_strings['s_calcerrincorrectargstofunction']=_("Incorrect arguments to function")
+ localized_strings['s_sheetfuncunknownfunction']=_("Unknown function")
+ localized_strings['s_sheetfunclnarg']=_("LN argument must be greater than 0")
+ localized_strings['s_sheetfunclog10arg']=_("LOG10 argument must be greater than 0")
+ localized_strings['s_sheetfunclogsecondarg']=_("LOG second argument must be numeric greater than 0")
+ localized_strings['s_sheetfunclogfirstarg']=_("LOG first argument must be greater than 0")
+ localized_strings['s_sheetfuncroundsecondarg']=_("ROUND second argument must be numeric")
+ localized_strings['s_sheetfuncddblife']=_("DDB life must be greater than 1")
+ localized_strings['s_sheetfuncslnlife']=_("SLN life must be greater than 1")
+ localized_strings['s_fdef_ABS']=_('Absolute value function. ')
+ localized_strings['s_fdef_ACOS']=_('Trigonometric arccosine function. ')
+ localized_strings['s_fdef_AND']=_('True if all arguments are true. ')
+ localized_strings['s_fdef_ASIN']=_('Trigonometric arcsine function. ')
+ localized_strings['s_fdef_ATAN']=_('Trigonometric arctan function. ')
+ localized_strings['s_fdef_ATAN2']=_('Trigonometric arc tangent function (result is in radians). ')
+ localized_strings['s_fdef_AVERAGE']=_('Averages the values. ')
+ localized_strings['s_fdef_CHOOSE']=_('Returns the value specified by the index. The values may be ranges of cells. ')
+ localized_strings['s_fdef_COLUMNS']=_('Returns the number of columns in the range. ')
+ localized_strings['s_fdef_COS']=_('Trigonometric cosine function (value is in radians). ')
+ localized_strings['s_fdef_COUNT']=_('Counts the number of numeric values, not blank, text, or error. ')
+ localized_strings['s_fdef_COUNTA']=_('Counts the number of non-blank values. ')
+ localized_strings['s_fdef_COUNTBLANK']=_("Counts the number of blank values. (Note: '' is not blank.) ")
+ localized_strings['s_fdef_COUNTIF']=_("Counts the number of number of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). ")
+ localized_strings['s_fdef_DATE']=_('Returns the appropriate date value given numbers for year, month, and day. For example: DATE(2006,2,1) for February 1, 2006. Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. ')
+ localized_strings['s_fdef_DAVERAGE']=_('Averages the values in the specified field in records that meet the criteria. ')
+ localized_strings['s_fdef_DAY']=_('Returns the day of month for a date value. ')
+ localized_strings['s_fdef_DCOUNT']=_('Counts the number of numeric values, not blank, text, or error, in the specified field in records that meet the criteria. ')
+ localized_strings['s_fdef_DCOUNTA']=_('Counts the number of non-blank values in the specified field in records that meet the criteria. ')
+ localized_strings['s_fdef_DDB']=_('Returns the amount of depreciation at the given period of time (the default factor is 2 for double-declining balance). ')
+ localized_strings['s_fdef_DEGREES']=_('Converts value in radians into degrees. ')
+ localized_strings['s_fdef_DGET']=_('Returns the value of the specified field in the single record that meets the criteria. ')
+ localized_strings['s_fdef_DMAX']=_('Returns the maximum of the numeric values in the specified field in records that meet the criteria. ')
+ localized_strings['s_fdef_DMIN']=_('Returns the maximum of the numeric values in the specified field in records that meet the criteria. ')
+ localized_strings['s_fdef_DPRODUCT']=_('Returns the result of multiplying the numeric values in the specified field in records that meet the criteria. ')
+ localized_strings['s_fdef_DSTDEV']=_('Returns the sample standard deviation of the numeric values in the specified field in records that meet the criteria. ')
+ localized_strings['s_fdef_DSTDEVP']=_('Returns the standard deviation of the numeric values in the specified field in records that meet the criteria. ')
+ localized_strings['s_fdef_DSUM']=_('Returns the sum of the numeric values in the specified field in records that meet the criteria. ')
+ localized_strings['s_fdef_DVAR']=_('Returns the sample variance of the numeric values in the specified field in records that meet the criteria. ')
+ localized_strings['s_fdef_DVARP']=_('Returns the variance of the numeric values in the specified field in records that meet the criteria. ')
+ localized_strings['s_fdef_EVEN']=_('Rounds the value up in magnitude to the nearest even integer. ')
+ localized_strings['s_fdef_EXACT']=_('Returns true if the values are exactly the same, including case, type, etc. ')
+ localized_strings['s_fdef_EXP']=_('Returns e raised to the value power. ')
+ localized_strings['s_fdef_FACT']=_('Returns factorial of the value. ')
+ localized_strings['s_fdef_FALSE']=_('Returns the logical value false. ')
+ localized_strings['s_fdef_FIND']=_('Returns the starting position within string2 of the first occurrence of string1 at or after start. If start is omitted, 1 is assumed. ')
+ localized_strings['s_fdef_FV']=_('Returns the future value of repeated payments of money invested at the given rate for the specified number of periods, with optional present value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). ')
+ localized_strings['s_fdef_HLOOKUP']=_('Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the row offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. ')
+ localized_strings['s_fdef_HOUR']=_('Returns the hour portion of a time or date/time value. ')
+ localized_strings['s_fdef_IF']=_('Results in true-value if logical-expression is TRUE or non-zero, otherwise results in false-value. ')
+ localized_strings['s_fdef_INDEX']=_('Returns a cell or range reference for the specified row and column in the range. If range is 1-dimensional, then only one of rownum or colnum are needed. If range is 2-dimensional and rownum or colnum are zero, a reference to the range of just the specified column or row is returned. You can use the returned reference value in a range, e.g., sum(A1:INDEX(A2:A10,4)). ')
+ localized_strings['s_fdef_INT']=_('Returns the value rounded down to the nearest integer (towards -infinity). ')
+ localized_strings['s_fdef_IRR']=_('Returns the interest rate at which the cash flows in the range have a net present value of zero. Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). ')
+ localized_strings['s_fdef_ISBLANK']=_('Returns true if the value is a reference to a blank cell. ')
+ localized_strings['s_fdef_ISERR']=_('Returns true if the value is of type Error but not NA. ')
+ localized_strings['s_fdef_ISERROR']=_('Returns true if the value is of type Error. ')
+ localized_strings['s_fdef_ISLOGICAL']=_('Returns true if the value is of type Logical (true/false). ')
+ localized_strings['s_fdef_ISNA']=_('Returns true if the value is the error type NA. ')
+ localized_strings['s_fdef_ISNONTEXT']=_('Returns true if the value is not of type Text. ')
+ localized_strings['s_fdef_ISNUMBER']=_('Returns true if the value is of type Number (including logical values). ')
+ localized_strings['s_fdef_ISTEXT']=_('Returns true if the value is of type Text. ')
+ localized_strings['s_fdef_LEFT']=_('Returns the specified number of characters from the text value. If count is omitted, 1 is assumed. ')
+ localized_strings['s_fdef_LEN']=_('Returns the number of characters in the text value. ')
+ localized_strings['s_fdef_LN']=_('Returns the natural logarithm of the value. ')
+ localized_strings['s_fdef_LOG']=_('Returns the logarithm of the value using the specified base. ')
+ localized_strings['s_fdef_LOG10']=_('Returns the base 10 logarithm of the value. ')
+ localized_strings['s_fdef_LOWER']=_('Returns the text value with all uppercase characters converted to lowercase. ')
+ localized_strings['s_fdef_MATCH']=_('Look for the matching value for the given value in the range and return position (the first is 1) in that range. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. If rangelookup is -1, act like 1 but the bracket is match>=value. ')
+ localized_strings['s_fdef_MAX']=_('Returns the maximum of the numeric values. ')
+ localized_strings['s_fdef_MID']=_('Returns the specified number of characters from the text value starting from the specified position. ')
+ localized_strings['s_fdef_MIN']=_('Returns the minimum of the numeric values. ')
+ localized_strings['s_fdef_MINUTE']=_('Returns the minute portion of a time or date/time value. ')
+ localized_strings['s_fdef_MOD']=_('Returns the remainder of the first value divided by the second. ')
+ localized_strings['s_fdef_MONTH']=_('Returns the month part of a date value. ')
+ localized_strings['s_fdef_N']=_('Returns the value if it is a numeric value otherwise an error. ')
+ localized_strings['s_fdef_NA']=_('Returns the #N/A error value which propagates through most operations. ')
+ localized_strings['s_fdef_NOT']=_('Returns FALSE if value is true, and TRUE if it is false. ')
+ localized_strings['s_fdef_NOW']=_('Returns the current date/time. ')
+ localized_strings['s_fdef_NPER']=_('Returns the number of periods at which payments invested each period at the given rate with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period) has the given present value. ')
+ localized_strings['s_fdef_NPV']=_('Returns the net present value of cash flows (which may be individual values and/or ranges) at the given rate. The flows are positive if income, negative if paid out, and are assumed at the end of each period. ')
+ localized_strings['s_fdef_ODD']=_('Rounds the value up in magnitude to the nearest odd integer. ')
+ localized_strings['s_fdef_OR']=_('True if any argument is true ')
+ localized_strings['s_fdef_PI']=_('The value 3.1415926... ')
+ localized_strings['s_fdef_PMT']=_('Returns the amount of each payment that must be invested at the given rate for the specified number of periods to have the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). ')
+ localized_strings['s_fdef_POWER']=_('Returns the first value raised to the second value power. ')
+ localized_strings['s_fdef_PRODUCT']=_('Returns the result of multiplying the numeric values. ')
+ localized_strings['s_fdef_PROPER']=_('Returns the text value with the first letter of each word converted to uppercase and the others to lowercase. ')
+ localized_strings['s_fdef_PV']=_('Returns the present value of the given number of payments each invested at the given rate, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). ')
+ localized_strings['s_fdef_RADIANS']=_('Converts value in degrees into radians. ')
+ localized_strings['s_fdef_RATE']=_('Returns the rate at which the given number of payments each invested at the given rate has the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). ')
+ localized_strings['s_fdef_REPLACE']=_('Returns text1 with the specified number of characters starting from the specified position replaced by text2. ')
+ localized_strings['s_fdef_REPT']=_('Returns the text repeated the specified number of times. ')
+ localized_strings['s_fdef_RIGHT']=_('Returns the specified number of characters from the text value starting from the end. If count is omitted, 1 is assumed. ')
+ localized_strings['s_fdef_ROUND']=_('Rounds the value to the specified number of decimal places. If precision is negative, then round to powers of 10. The default precision is 0 (round to integer). ')
+ localized_strings['s_fdef_ROWS']=_('Returns the number of rows in the range. ')
+ localized_strings['s_fdef_SECOND']=_('Returns the second portion of a time or date/time value (truncated to an integer). ')
+ localized_strings['s_fdef_SIN']=_('Trigonometric sine function (value is in radians) ')
+ localized_strings['s_fdef_SLN']=_('Returns the amount of depreciation at each period of time using the straight-line method. ')
+ localized_strings['s_fdef_SQRT']=_('Square root of the value ')
+ localized_strings['s_fdef_STDEV']=_('Returns the sample standard deviation of the numeric values. ')
+ localized_strings['s_fdef_STDEVP']=_('Returns the standard deviation of the numeric values. ')
+ localized_strings['s_fdef_SUBSTITUTE']=_('Returns text1 with the all occurrences of oldtext replaced by newtext. If occurrence is present, then only that occurrence is replaced. ')
+ localized_strings['s_fdef_SUM']=_('Adds the numeric values. The values to the sum function may be ranges in the form similar to A1:B5. ')
+ localized_strings['s_fdef_SUMIF']=_("Sums the numeric values of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). If range2 is present, then range1 is tested and the corresponding range2 value is summed. ")
+ localized_strings['s_fdef_SYD']=_("Depreciation by Sum of Year's Digits method. ")
+ localized_strings['s_fdef_T']=_('Returns the text value or else a null string. ')
+ localized_strings['s_fdef_TAN']=_('Trigonometric tangent function (value is in radians) ')
+ localized_strings['s_fdef_TIME']=_('Returns the time value given the specified hour, minute, and second. ')
+ localized_strings['s_fdef_TODAY']=_('Returns the current date (an integer). Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. ')
+ localized_strings['s_fdef_TRIM']=_('Returns the text value with leading, trailing, and repeated spaces removed. ')
+ localized_strings['s_fdef_TRUE']=_('Returns the logical value true. ')
+ localized_strings['s_fdef_TRUNC']=_('Truncates the value to the specified number of decimal places. If precision is negative, truncate to powers of 10. ')
+ localized_strings['s_fdef_UPPER']=_('Returns the text value with all lowercase characters converted to uppercase. ')
+ localized_strings['s_fdef_VALUE']=_('Converts the specified text value into a numeric value. Various forms that look like numbers (including digits followed by %, forms that look like dates, etc.) are handled. This may not handle all of the forms accepted by other spreadsheets and may be locale dependent. ')
+ localized_strings['s_fdef_VAR']=_('Returns the sample variance of the numeric values. ')
+ localized_strings['s_fdef_VARP']=_('Returns the variance of the numeric values. ')
+ localized_strings['s_fdef_VLOOKUP']=_('Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the column offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match>=value) instead of exact match. ')
+ localized_strings['s_fdef_WEEKDAY']=_('Returns the day of week specified by the date value. If type is 1 (the default), Sunday is day and Saturday is day 7. If type is 2, Monday is day 1 and Sunday is day 7. If type is 3, Monday is day 0 and Sunday is day 6. ')
+ localized_strings['s_fdef_YEAR']=_('Returns the year part of a date value. ')
+ localized_strings['s_farg_v']=_("value")
+ localized_strings['s_farg_vn']=_("value1, value2, ...")
+ localized_strings['s_farg_xy']=_("valueX, valueY")
+ localized_strings['s_farg_choose']=_("index, value1, value2, ...")
+ localized_strings['s_farg_range']=_("range")
+ localized_strings['s_farg_rangec']=_("range, criteria")
+ localized_strings['s_farg_date']=_("year, month, day")
+ localized_strings['s_farg_dfunc']=_("databaserange, fieldname, criteriarange")
+ localized_strings['s_farg_ddb']=_("cost, salvage, lifetime, period [, factor]")
+ localized_strings['s_farg_find']=_("string1, string2 [, start]")
+ localized_strings['s_farg_fv']=_("rate, n, payment, [pv, [paytype]]")
+ localized_strings['s_farg_hlookup']=_("value, range, row, [rangelookup]")
+ localized_strings['s_farg_iffunc']=_("logical-expression, true-value, false-value")
+ localized_strings['s_farg_index']=_("range, rownum, colnum")
+ localized_strings['s_farg_irr']=_("range, [guess]")
+ localized_strings['s_farg_tc']=_("text, count")
+ localized_strings['s_farg_log']=_("value, base")
+ localized_strings['s_farg_match']=_("value, range, [rangelookup]")
+ localized_strings['s_farg_mid']=_("text, start, length")
+ localized_strings['s_farg_nper']=_("rate, payment, pv, [fv, [paytype]]")
+ localized_strings['s_farg_npv']=_("rate, value1, value2, ...")
+ localized_strings['s_farg_pmt']=_("rate, n, pv, [fv, [paytype]]")
+ localized_strings['s_farg_pv']=_("rate, n, payment, [fv, [paytype]]")
+ localized_strings['s_farg_rate']=_("n, payment, pv, [fv, [paytype, [guess]]]")
+ localized_strings['s_farg_replace']=_("text1, start, length, text2")
+ localized_strings['s_farg_vp']=_("value, [precision]")
+ localized_strings['s_farg_valpre']=_("value, precision")
+ localized_strings['s_farg_csl']=_("cost, salvage, lifetime")
+ localized_strings['s_farg_cslp']=_("cost, salvage, lifetime, period")
+ localized_strings['s_farg_subs']=_("text1, oldtext, newtext [, occurrence]")
+ localized_strings['s_farg_sumif']=_("range1, criteria [, range2]")
+ localized_strings['s_farg_hms']=_("hour, minute, second")
+ localized_strings['s_farg_txt']=_("text")
+ localized_strings['s_farg_vlookup']=_("value, range, col, [rangelookup]")
+ localized_strings['s_farg_weekday']=_("date, [type]")
+ localized_strings['s_farg_dt']=_("date")
+ localized_strings['s_fclass_all']=_("All")
+ localized_strings['s_fclass_stat']=_("Statistics")
+ localized_strings['s_fclass_lookup']=_("Lookup")
+ localized_strings['s_fclass_datetime']=_("Date & Time")
+ localized_strings['s_fclass_financial']=_("Financial")
+ localized_strings['s_fclass_test']=_("Test")
+ localized_strings['s_fclass_math']=_("Math")
+ localized_strings['s_fclass_text']=_("Text")
+
+ localized_strings['s_loc_plain']=_("Plain")
+ localized_strings['s_loc_graph']=_("Graph")
+ localized_strings['s_loc_cells_to_graph']=_("Cells to Graph")
+ localized_strings['s_loc_set_cells_to_graph']=_("Set Cells To Graph")
+ localized_strings['s_loc_graph_type']=_("Graph Type")
+ localized_strings['s_loc_help']=_("Help")
+ localized_strings['s_loc_horizontal_bar']=_("Horizontal Bar")
+ localized_strings['s_loc_vertical_bar']=_("Vertical Bar")
+ localized_strings['s_loc_pie_chart']=_("Pie Chart")
+ localized_strings['s_loc_line_chart']=_("Line Chart")
+ localized_strings['s_loc_scatter_chart']=_("Plot Points")
+ localized_strings['s_loc_not_set']=_("Not Set")
+ localized_strings['s_loc_unknown_range_name']=_("Unknown range name")
+ localized_strings['s_loc_hide_help ']=_("Hide Help")
+
+ localized_strings['s_loc_x']=_("X ")
+ localized_strings['s_loc_y']=_("Y ")
+ localized_strings['s_loc_max']=_("Max ")
+ localized_strings['s_loc_min']=_("Min ")
+ localized_strings['s_loc_ok']=_(" OK ")
+
+ localized_strings['s_PopupListCustom']=_("Custom")
+
+
+add_localized_strings()
diff --git a/logic.py b/logic.py
new file mode 100644
index 0000000..d02c338
--- /dev/null
+++ b/logic.py
@@ -0,0 +1,364 @@
+# Copyright (c) 2008, Media Modifications Ltd.
+
+#Permission is hereby granted, free of charge, to any person obtaining a copy
+#of this software and associated documentation files (the "Software"), to deal
+#in the Software without restriction, including without limitation the rights
+#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+#copies of the Software, and to permit persons to whom the Software is
+#furnished to do so, subject to the following conditions:
+
+#The above copyright notice and this permission notice shall be included in
+#all copies or substantial portions of the Software.
+
+#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+#THE SOFTWARE.
+
+
+from result import ServerResult
+from constants import Constants
+from instance import Instance
+
+from threading import Thread
+import threading
+import os
+import gobject
+import time
+import gtk
+import urllib
+
+class ServerLogic:
+ def __init__(self, ca):
+ self.ca = ca
+ self.proceedTxt = ""
+ self.proceedHeaders = []
+ self.cond = ca.cond
+ self.addKMLSet=0
+
+ def doServerLogic(self, url, path, params):
+ #self.ca.remoteServerActive( True )
+ r = ServerResult()
+ fileName = path[len(path)-1]
+
+ if (fileName == "comet.js"):
+
+ #clear...
+ self.proceedHeaders = []
+ self.proceedTxt = ""
+
+ #wait...
+ self.cond.acquire()
+ self.cond.wait()
+ self.cond.release()
+
+ #prep response...
+ for h in range( len(self.proceedHeaders) ):
+ r.headers.append( self.proceedHeaders[h] )
+ #r.txt = ""+self.proceedTxt
+ #self.ca.browser.load_uri("javascript:"+r.txt+"void(0);")
+
+ else:
+ kickThroughComet = True
+
+ if (fileName =="cometor.js"):
+ gobject.idle_add(self.ca.send_to_browser_localize,['initlocalize']);
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = ""
+
+ if (fileName =="mediaQuery.js"):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = self.ca.m.getMediaResponse( params[0][1], params[1][1], params[2][1], params[3][1] )
+
+ elif (fileName == "showMedia.js"):
+ id = params[0][1]
+ locX = params[1][1]
+ locY = params[2][1]
+ up = params[3][1]
+ rt = params[4][1]
+ gobject.idle_add(self.ca.showMedia, id, locX, locY, up=='true', rt=='true')
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+
+ elif (fileName == "placeAddMedia.js"):
+ lat = params[0][1]
+ lng = params[1][1]
+ gobject.idle_add(self.ca.placeAddMedia, lat, lng)
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ kickThroughComet = False
+
+ elif (fileName == "hideMedia.js"):
+ gobject.idle_add(self.ca.hideMedia)
+
+ elif (fileName == "getImage.js"):
+ localfile = open(os.path.join(Instance.instancePath, params[0][1]), 'r')
+ localdata = localfile.read()
+ localfile.close()
+
+ #one day we might need to kick you through comet as a base64'd image.
+ r.txt = localdata
+ r.headers.append( ("Content-type", "image/jpeg") )
+ kickThroughComet = False
+
+ elif (fileName == "updateLocation.js"):
+ lat = params[0][1]
+ lng = params[1][1]
+ zoom = params[2][1]
+ x = params[3][1]
+ y = params[4][1]
+ gobject.idle_add(self.ca.updateMapMetaData,lat,lng,zoom,x,y)
+
+ elif (fileName == "addSavedMap.js"):
+ # allow internet to send an array of SavedMaps back to map.py
+ latitudes = params[0][1]
+ longitudes = params[1][1]
+ zooms = params[2][1]
+ notes = params[3][1]
+ gobject.idle_add(self.ca.addSavedMap,latitudes,longitudes,zooms,urllib.unquote(notes),True)
+
+ elif (fileName == "addInfoMarker.js"):
+ lat = params[0][1]
+ lng = params[1][1]
+ info = params[2][1]
+ icon = params[3][1]
+ if(params[4][1] == "True"):
+ isNew = True
+ gobject.idle_add(self.ca.cometLogic.forceupdate)
+ else:
+ isNew = False
+ gobject.idle_add(self.ca.addInfoMarker,lat,lng,info,icon,isNew)
+
+ elif (fileName == "addLine.js"):
+ id = params[0][1]
+ color = params[1][1]
+ thickness = params[2][1]
+ pts = params[3][1] # send pts separated with | instead of ,
+ gobject.idle_add(self.ca.addLine,id,color,thickness,pts,1)
+
+ elif (fileName == "promptSearch.js"):
+ address = params[0][1]
+ time.sleep(0.5)
+ self.ca.preComet()
+ self.handleAddressUpdate(address+"+")
+ self.ca.postComet()
+
+ #elif (fileName == "gotoMapV3.js"):
+ # button on static maps links to mapv3
+ #self.ca.loadMapV3()
+
+ if (kickThroughComet):
+ #not sure how & why this goes out, but it does.
+ self.cond.acquire()
+ self.cond.notifyAll()
+ self.cond.release()
+ time.sleep(.1)
+
+ return r
+
+ def handleAddressUpdate( self, address ):
+ findsrc="http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=" + urllib.quote(address)
+ findAddress = urllib.urlopen(findsrc).read()
+
+ longname=findAddress[findAddress.find('long_name')+13:len(findAddress)]
+ longname=longname[0:longname.find('"')]
+
+ findSW=findAddress[findAddress.find('southwest'):findAddress.find('northeast')].replace(" ","").replace('\n','')
+ swlat=findSW[findSW.find('lat')+5:findSW.find(',')]
+ swlng=findSW[findSW.find('lng')+5:findSW.find('}')]
+
+ findNE=findAddress[findAddress.find('northeast'):len(findAddress)].replace(" ","").replace('\n','')
+ nelat=findNE[findNE.find('lat')+5:findNE.find(',')]
+ nelng=findNE[findNE.find('lng')+5:findNE.find('}')]
+
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ #self.proceedTxt = "showInfo('" + swlat + "," + swlng + "," + nelat + "," + nelng + "');"
+ self.proceedTxt = "moveToAddress(" + swlat + "," + swlng + "," + nelat + "," + nelng + ",'" + longname + "');"
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ def forceupdate(self):
+ #self.ca.preComet()
+
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = "canvas.updateImg();"
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+ #self.ca.postComet()
+
+ def handleCompassUpdate( self, dir ):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+
+ if (dir == "e"):
+ self.proceedTxt = "dirEast();"
+ elif (dir == "w"):
+ self.proceedTxt = "dirWest();"
+ elif (dir == "n"):
+ self.proceedTxt = "dirNorth();"
+ elif (dir == "s"):
+ self.proceedTxt = "dirSouth();"
+ else:
+ # use this as a print warning window
+ self.proceedTxt = 'showInfo("' + dir + '");'
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ def handlePanoramio(self):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = 'panoramio();'
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ def handleLocalWiki(self):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = 'wikiloc();'
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ def handleWikiMapia(self):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = 'wikimapia();'
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ def handleOlpcMAP(self):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ llc=[float(self.ca.NOW_MAP_CENTER_LAT),float(self.ca.NOW_MAP_CENTER_LNG)]
+ llz=float(self.ca.NOW_MAP_ZOOM)
+ lln=llc[0]+0.55618*0.75*(2**(9-llz))
+ lle=llc[1]+0.98877*0.75*(2**(9-llz))
+ lls=llc[0]-0.55618*0.75*(2**(9-llz))
+ llw=llc[1]-0.98877*0.75*(2**(9-llz))
+ findsrc="http://mapmeld.appspot.com/olpcMAP/kml?llregion="+str(lln)+","+str(lle)+","+str(lls)+","+str(llw)
+ self.ca.readKML(urllib.urlopen(findsrc))
+
+ def handleZoomUpdate( self, dir ):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ if (dir == "+"):
+ self.proceedTxt = "zoomIn();"
+ elif (dir == "-"):
+ self.proceedTxt = "zoomOut();"
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ def handleClear( self ):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = "clear();"
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ def handlePreAdd( self ):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = "preAddMedia();"
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ def handlePreAddInfo( self ):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = "preAddInfo();"
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ def handlePostAdd( self, rec ):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = "postAddMedia(" + rec.latitude + ", " + rec.longitude + ", '" + rec.getThumbUrl() + "', '" + rec.getThumbBasename() + "', '" + rec.tags + "');"
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ def handleDelete( self ):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = "deleteMedia();"
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ # handle a map that was sent to us
+ def handleReceivedMap( self, lat, lng, zoom):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = "setMap(" + lat + "," + lng + "," + zoom + ");"
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ def handleSavedMap( self, lat, lng, zoom, info ):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ if(info.find("Describe the map") != 0):
+ self.proceedTxt = "setMap2(" + lat + "," + lng + "," + zoom + ",'" + urllib.quote(info) + "');"
+ else:
+ self.proceedTxt = "setMap2(" + lat + "," + lng + "," + zoom + ",'');"
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ # handle a marker that was sent to us
+ def handleAddMarker( self, lat, lng, pixString, icon ):
+ if(self.addKMLSet < 1):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = ""
+ if(self.addKMLSet == -1):
+ self.addKMLSet = 1
+ self.proceedTxt = self.proceedTxt + "addInfoMarker(" + lat + ", " + lng + ", '" + pixString.replace("'",'"') + "', '" + icon + "',false);"
+ #self.proceedTxt = self.proceedTxt + "addInfoMarker(" + lat + ", " + lng + ", '"+pixString.replace("'",'"')+"', 'http://mapmeld.appspot.com/xo-red.png',false);"
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ def startKML( self, tellOthers ):
+ self.addKMLSet = -1
+ if((self.ca.maptube is not None) and (tellOthers == 1)):
+ self.ca.sendStartKML()
+
+ def handleEndKML( self, tellOthers ):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = self.proceedTxt + "canvas.updateImg();"
+ self.addKMLSet = 0
+ if((self.ca.maptube is not None) and (tellOthers == 1)):
+ self.ca.sendEndKML()
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ def lineMode(self, type):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = "lineMode('" + type + "');"
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ def handleLine(self,id,color,thickness,pts):
+ if(self.addKMLSet < 1):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = ""
+ if(self.addKMLSet == -1):
+ self.addKMLSet = 1
+ self.proceedTxt = self.proceedTxt + "addLine('" + id + "','" + color + "','" + thickness + "','" + pts + "');"
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ # handle start of measure tool
+ def handleMeasure(self):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = "measure();"
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
+
+ def handleTagSearch( self, tags ):
+ self.proceedHeaders.append( ("Content-type", "text/javascript") )
+ self.proceedTxt = "filterTags('" + tags + "');"
+ self.ca.ajaxServer.stop()
+ self.ca.cometServer.stop()
+ self.ca.browser.load_uri("javascript:"+self.proceedTxt+";void(0);")
diff --git a/news b/news
new file mode 100644
index 0000000..b51e119
--- /dev/null
+++ b/news
@@ -0,0 +1,59 @@
+5.0 - January 22, 2010
+* Localization in Spanish, Afrikaans, Hindi, Japanese, Arabic, Russian, Chinese (simplified), French, German and Portuguese.
+ Localization infrastructure developed by Vijit Singh, Software Engineer at SEETA (http://seeta.in) under the guidance of
+ Manusheel Gupta with pointers from Dan Bricklin.
+ Spanish translation undertaken by Claudia Urrea and Reuben Caron, and integrated to the SocialCalc activity by Diksha Khatri
+ from SEETA (http://seeta.in) and Vijit.
+ Localization in Afrikaans, Japanese, Arabic and Russian undertaken by Sakshi Chawla from SEETA (http://seeta.in) using google translator,
+ and integrated by Vijit.
+ Localization in Chinese (simplified), French, Hindi, German and Portuguese undertaken by Diksha Khatri and Lakky Rawat from
+ SEETA (http://seeta.in) using google translator, and integrated by Vijit.
+
+4.0 - January 5, 2010
+* Ability to read single sheet Excel .xls files in SocialCalc added. Developed by Mahesh Chand Sharma from SEETA (http://seeta.in) and Vijit Singh,
+ Software Engineer at SEETA (http://seeta.in) under the guidance of Manusheel Gupta.
+
+3.0 - December 4 2009
+* Ability to read single sheet Lotus .wk4 files in SocialCalc added. Developed by Vijit Singh, Software Engineer at SEETA (http://seeta.in)
+ under the guidance of Manusheel Gupta.
+
+2.0 - October 25 2009
+* Optimization of the save files. The sheet extents are more likely to include just the part that has data.
+ Previously there were cases where deleted cells made the program think the sheet was larger than it really was.
+ It also "canonicalizes" the saved data in other ways, such as removing no longer used formats and color definitions from the save file.
+ Some input forms, such as "-", that were incorrectly treated as numbers, are now treated as text. Some other minor bugs were fixed.
+* Localization made easy, especially of text in the user interface.
+ All of the text that is normally seen during operation should now be easily localizable by changing a single file, socialcalcconstants.js.
+
+1.0 - July 12 2009
+* Sharing of socialcalc activity over the mesh network. Developed by Vijit Singh, Software Engineer at SEETA (http://seeta.in)
+under the guidance of Manusheel Gupta. Documentation available at http://seeta.in/wiki/index.php?title=Collaboration_in_SocialCalc .
+
+0.8.3g - June 22 2009
+*Enhanced graphing added by Nick Doiron under the guidance of Manusheel Gupta
+*Fixes a bug about special characters in custom values, such as number format definitions.
+
+0.8.2 - June 14 2009
+* Conditionals in custom formats and with the argument prompt for VLOOKUP.
+
+0.8.1 - June 1 2009
+* Function dialog box, a link dialog box, and a multi-line input dialog box added.
+* Improved vertical scrolling, improved Format tab with many more formats.
+* Ctrl-C and -Z keyboard shortcuts, and a better UI for graphs and an API for adding graphs.
+
+0.7.9 - January 11 2009
+* Status bar and color choosers added.
+* Commands, recalculation, and redisplay more robust.
+
+0.7.5 - Tue April 15 00:14:58 EDT 2008
+* Now with synchrous method calling
+* Saves and Loads from Journal
+* SVG taken from: http://openclipart.org/media/files/yamazaki/1481
+
+0.7.0 - February 22 2008
+*Version 0.7.0 released.
+*109 planned formula functions available, along with a simple reference listing them, their arguments, and a brief description on the Help tab.
+
+0.6.3 - February 15 2008
+*Version 0.6.3 released.
+*Formula functions, copy/cut/paste, merge/unmerge, insert/delete row/column added
diff --git a/po/af.po b/po/af.po
new file mode 100644
index 0000000..a0f832b
--- /dev/null
+++ b/po/af.po
@@ -0,0 +1,1476 @@
+# Copyright (C) 2010 THE PACKAGE"S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# olpc user <olpc@localhost.localdomain>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: SocialCalcActivity.activity\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-01-07 14:46+0000\n"
+"PO-Revision-Date: 2010-01-09 21:53+0530\n"
+"Last-Translator: Diksha<dksh.khatri@gmail.com>\n"
+"Language-Team: Hindi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: activity/activity.info:2
+msgid "SocialCalcActivity"
+msgstr "SocialCalcActivity"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:10
+#msgid "t"
+#msgstr "t"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:13
+msgid "Browser not supported. "
+msgstr "Leser nie ondersteun nie. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:14
+msgid "Internal SocialCalc error (probably an internal bug):"
+msgstr "Interne SocialCalc fout (waarskynlik 'n interne fout):"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:20
+msgid "Unknown col type item"
+msgstr "Onbekend col tipe item"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:21
+msgid "Unknown row type item"
+msgstr "Onbekend ry tipe item"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:22
+msgid "Unknown line type"
+msgstr "Onbekend lyn tipe"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:28
+msgid "Unknown cell type item"
+msgstr "Onbekend sel tipe item"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:36
+msgid "Unknown sheet command: "
+msgstr "Onbekende blad opdrag: "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:37
+msgid "Unknown set coord command: "
+msgstr "Onbekend ingestel coord opdrag: "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:38
+msgid "Unknown command: "
+msgstr "Onbekende opdrag: "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:42
+msgid "Circular reference to "
+msgstr "Omsendbrief verwysing na "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:52
+msgid "padding:2px 2px 1px 2px;vertical-align:top;"
+msgstr "padding: 2px 2px 1px 2px; vertical-align: top;"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:53
+msgid "normal normal"
+msgstr "normaal normale"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:54
+msgid "small"
+msgstr "klein"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:55
+msgid "Verdana,Arial,Helvetica,sans-serif"
+msgstr "Verdana, Arial, Helvetica, sans-serif"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:92
+msgid "Render Context must have a sheet object"
+msgstr "Render konteks moet 'n plaat voorwerp"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Executing..."
+msgstr "Uitvoerende ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Displaying..."
+msgstr "Displaying ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Ordering..."
+msgstr "Bestel ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating..."
+msgstr "Berekening..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating... Loading Sheet..."
+msgstr "Berekening van ... Laai Fiche ..."
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "doing server function "
+msgstr "doen bediener funksie "
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " in cell "
+msgstr "in sel "
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculation start..."
+msgstr "Berekening begin ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SUM"
+msgstr "BEDRAG"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Multi-line text: Click icon on right to edit]"
+msgstr "[Multi-lyn teks: Klik op die ikoon regs te wysig]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function "
+msgstr "Onbekende funksie "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane vertically"
+msgstr "Sleep om sluis paneel vertikaal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane horizontally"
+msgstr "Sleep om venster slot horisontaal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Center"
+msgstr "Rig Middel"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Left"
+msgstr "Links Regterkant"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Right"
+msgstr "Lijn regs uit"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Alignment"
+msgstr "Regterkant"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit"
+msgstr "Oudit"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit Trail This Session"
+msgstr "Audit trail Hierdie Sessie"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto"
+msgstr "Auto"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto Sum"
+msgstr "Auto-Som"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto w/ commas"
+msgstr "Auto-w / kommas"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Automatic"
+msgstr "Outomatiese"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Background"
+msgstr "Agtergrond"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold"
+msgstr "Vet"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold &amp; Italics"
+msgstr "Vet & Kursief"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold Italic"
+msgstr "Vetdruk Kursief"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders"
+msgstr "Grense"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders Off"
+msgstr "Grense Off"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders On"
+msgstr "Grense Op"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom"
+msgstr "Onderkant"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom Border"
+msgstr "Bottom-grens"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CELL SETTINGS"
+msgstr "CELL SETTINGS"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CSV format"
+msgstr "CSV formaat"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cancel"
+msgstr "Styl"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Category"
+msgstr "Kategorie"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Center"
+msgstr "Sentrum"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear"
+msgstr "Helder"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear SocialCalc Clipboard"
+msgstr "Duidelik SocialCalc Klembord"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clipboard"
+msgstr "Clipboard"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Color"
+msgstr "Kleur"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Column"
+msgstr "Kolom"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Comment"
+msgstr "Kommentaar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Copy"
+msgstr "Kopie"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Custom"
+msgstr "Gewoonte"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cut"
+msgstr "Sny"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default"
+msgstr "Verstek"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Alignment"
+msgstr "Standaard Orde"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Column Width"
+msgstr "Standaard Kolom Breedte"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Font"
+msgstr "Standaard Lettertipe"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Format"
+msgstr "Standaard Formaat"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Padding"
+msgstr "Standaard Padding"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete"
+msgstr "Skrap"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Column"
+msgstr "Verwyder kolom"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Contents"
+msgstr "Inhoud verwyder"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Row"
+msgstr "Verwyder ry"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Description"
+msgstr "Beskrywing"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Display Clipboard in"
+msgstr "Display Klembord in"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Down"
+msgstr "Af"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Edit"
+msgstr "Edit"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Existing Names"
+msgstr "Bestaande Name"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Family"
+msgstr "Familie"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Down"
+msgstr "Vul Down"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Right"
+msgstr "Vul Right"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Font"
+msgstr "Skrif"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Format"
+msgstr "Formaat"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula"
+msgstr "Formule"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Function List"
+msgstr "Funksie Lys"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Functions"
+msgstr "Funksies"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Grid"
+msgstr "Grid"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hidden"
+msgstr "Verborge"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal"
+msgstr "Horisontale"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Column"
+msgstr "Insert Kolom"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Row"
+msgstr "Insert Row"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Italic"
+msgstr "Italic"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Last Sort"
+msgstr "Laaste Sorteer"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left"
+msgstr "Links"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left Border"
+msgstr "Links Grens"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link"
+msgstr "Skakel"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link Input Box"
+msgstr "Skakel Invoer Box"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "List"
+msgstr "Lys"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Load SocialCalc Clipboard With This"
+msgstr "Load SocialCalc Klembord Met hierdie"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Major Sort"
+msgstr "Groot Sorteer"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Manual"
+msgstr "Handleiding"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Merge Cells"
+msgstr "Saamsmelt Selle"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Middle"
+msgstr "MIDDEL"
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Minor Sort"
+msgstr "Mineur Sorteer"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Insert"
+msgstr "Beweeg Plaas"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Paste"
+msgstr "Beweeg Plak"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Multi-line Input Box"
+msgstr "Multi-lyn Invoer Box"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Name"
+msgstr "Naam"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Names"
+msgstr "Name"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "No padding"
+msgstr "Geen padding"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Normal"
+msgstr "Normale"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number"
+msgstr "Nommer"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number Horizontal"
+msgstr "Nommer Horisontale"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "OK"
+msgstr "OK"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Padding"
+msgstr "Padding"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Page Name"
+msgstr "Bladsy Naam"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste"
+msgstr "Plak"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste Formats"
+msgstr "Plak Formats"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain Text"
+msgstr "Plain Text"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalc"
+msgstr "Herb Reken"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalculation"
+msgstr "Herberekening"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " Redo"
+msgstr " Oordoen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right"
+msgstr "Reg"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right Border"
+msgstr "Right-grens"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SHEET SETTINGS"
+msgstr "BLAD SETTINGS"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save"
+msgstr "Spaar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save to"
+msgstr "Slaan na"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cell Contents"
+msgstr "Set Cell Inhoud"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Sort"
+msgstr "Set Selle Om te sorteer"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Value To"
+msgstr "Set Waarde Om"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set to Link format"
+msgstr "Ingestel op Link formaat"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set/Clear Move From"
+msgstr "Set / Duidelike Move Van"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Cell Settings"
+msgstr "Wys Cell Stellings"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Sheet Settings"
+msgstr "Wys Fiche Stellings"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show in new browser window"
+msgstr "Show in nuwe venster"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Size"
+msgstr "Grootte"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SocialCalc-save format"
+msgstr "SocialCalc-red-formaat"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort"
+msgstr "Sorteer"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort Cells"
+msgstr "Sorteer Selle"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Swap Colors"
+msgstr "Swap Colors"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Tab-delimited format"
+msgstr "Tabgescheiden formaat"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text"
+msgstr "Text"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text Horizontal"
+msgstr "Text Horisontale"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "This is a<br>sample"
+msgstr "Hierdie is 'n<br>monster"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top"
+msgstr "Top"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top Border"
+msgstr "Bo-grens"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "UNDONE STEPS"
+msgstr "Undone STAPPE"
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "URL"
+msgstr "URL"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Undo"
+msgstr "Boontoe"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unmerge Cells"
+msgstr "Unmerge Selle"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Up"
+msgstr "Op"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Value"
+msgstr "Waarde"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical"
+msgstr "Vertikale"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Workspace"
+msgstr "Werkplek"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[New]"
+msgstr "[New]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[None]"
+msgstr "[Geen]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[select range]"
+msgstr "[kies verskeidenheid]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
+#msgstr ["Domingo", "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
+#msgstr ["Dom", "Lun", "Mar", "Mie", "Jue", "Vie", "Sab"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["January", "February", "March", "April", "May", "June", "July", "August", "September","October", "November", "December"]
+#msgstr ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"],
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+#msgstr ["Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "AM"
+#msgstr "AM"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "A"
+#msgstr "A"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "PM"
+#msgstr "PM"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "P"
+#msgstr "P"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed number exponent"
+msgstr "Verkeerd is gevorm nommer eksponent"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unexpected character in formula"
+msgstr "Onverwagte karakter in die formule"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed string"
+msgstr "Verkeerd is gevorm snaar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed special value"
+msgstr "Verkeerd is gevorm besondere waarde"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula (two operators inappropriately in a row)"
+msgstr "Fout in die formule (twee operateurs ontoepaslik in 'n ry)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing open parenthesis in list with comma(s)."
+msgstr "Missing oop tussen hakies in die lys met komma (s) gevind."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Closing parenthesis without open parenthesis. "
+msgstr "Sluitingsdatum hakies, sonder oop hakies. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing close parenthesis."
+msgstr "Missing naby hakies."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing operand."
+msgstr "Missing operand."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula."
+msgstr "Fout in die formule."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error value in formula"
+msgstr "Waarde fout in die formule"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula resulting in bad value"
+msgstr "Fout in die formule wat lei tot slegte waarde"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in range value:"
+msgstr "Formule resultate in reeks waarde:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in an bad numeric value"
+msgstr "Formule resultate in 'n slegte numeriese waarde"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Numeric overflow"
+msgstr "Numeriese oorloop"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet unavailable:"
+msgstr "Sheet nie beskikbaar nie:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cell reference missing when expected."
+msgstr "Selverwysing ontbreek as wat verwag is."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet name missing when expected."
+msgstr "Sheet naam ontbreek as wat verwag is."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Circular name reference to name"
+msgstr "Omsendbrief naam verwysing na die naam"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown name"
+msgstr "Onbekend naam"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Incorrect arguments to function"
+msgstr "Verkeerde argumente om te funksioneer"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function"
+msgstr "Onbekende funksie"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LN argument must be greater than 0"
+msgstr "LN argument moet groter as 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG10 argument must be greater than 0"
+msgstr "Log10 argument moet groter as 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG second argument must be numeric greater than 0"
+msgstr "LOG tweede argument moet numeriese groter as 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG first argument must be greater than 0"
+msgstr "LOG eerste argument moet groter as 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "ROUND second argument must be numeric"
+msgstr "RONDTE tweede argument moet numeries wees"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "DDB life must be greater than 1"
+msgstr "DDB lewe moet groter as 1"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SLN life must be greater than 1"
+msgstr "SLN lewe moet groter as 1"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Absolute value function. "
+msgstr "Absolute waarde-funksie. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arccosine function. "
+msgstr "Trigonometriese arccosine funksie. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if all arguments are true. "
+msgstr "Waar indien al die argumente waar is. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arcsine function. "
+msgstr "Trigonometriese arcsine funksie. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arctan function. "
+msgstr "Trigonometriese funksie arctan. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arc tangent function (result is in radians). "
+msgstr "Trigonometriese boog tangens funksie (resultaat is in radiale). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values. "
+msgstr "Gemiddeldes van die waardes."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value specified by the index. The values may be ranges of cells. "
+msgstr "Opgawes die waarde bepaal deur die indeks. Die waardes kan wissel van selle word. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of columns in the range. "
+msgstr "Opgawes van die aantal kolomme in die reeks. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric cosine function (value is in radians). "
+msgstr "Trigonometriese kosinus funksie (waarde is in radiale)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error. "
+msgstr "Tel die aantal numeriese waardes, nie leeg is, teks, of foute. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values. "
+msgstr "Tel die aantal nie-leë waardes. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of blank values. (Note: '' is not blank.) "
+msgstr "Tel die aantal leë waardes. (Nota:''nie leeg is.) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of number of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). "
+msgstr "Tel die hoeveelheid van die aantal van die selle in die reeks wat voldoen aan die kriteria. Die kriteria kan wees van 'n waarde (' x ', 15, 1 3) of' n toets (> 25). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the appropriate date value given numbers for year, month, and day. For example: DATE(2006,2,1) for February 1, 2006. Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "Opbrengste van die betrokke datum waarde gegee syfers vir die jaar, maand en dag. Byvoorbeeld: DATUM (2006,2,1) vir 1 Februarie 2006. Let wel: In hierdie program, dag 1 is 31 Desember 1899 en die jaar 1900 is nie 'n skrikkeljaar. Sommige programme gebruik 1 Januarie 1900, soos dag 1 en behandeling van 1900 as 'n skrikkeljaar. In beide gevalle, alhoewel, datums op of na 1 Maart 1900, is dieselfde. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values in the specified field in records that meet the criteria. "
+msgstr "Gemiddeldes van die waardes in die gekose veld in die rekords wat aan die kriteria voldoen. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of month for a date value. "
+msgstr "Opbrengste van die dag van die maand vir 'n datum waarde. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error, in the specified field in records that meet the criteria. "
+msgstr "Tel die aantal numeriese waardes, nie leeg is, teks, of fout in die gekose veld in die rekords wat voldoen aan die kriteria. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values in the specified field in records that meet the criteria. "
+msgstr "Tel die aantal nie-leë waarde in die gekose veld in die rekords wat voldoen aan die kriteria. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at the given period of time (the default factor is 2 for double-declining balance). "
+msgstr "Opgawes van die bedrag van waardevermindering op die gegewe tyd (die standaard-faktor is 'n 2 vir dubbel-afnemende balans). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in radians into degrees. "
+msgstr "Bekeerlinge waarde in radiale na grade. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value of the specified field in the single record that meets the criteria. "
+msgstr "Opgawes van die waarde van die gespesifiseerde veld in die enkele rekord wat voldoen aan die kriteria. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Opgawes van die maksimum van die numeriese waardes van die gespesifiseerde veld in die rekords wat aan die kriteria voldoen. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values in the specified field in records that meet the criteria. "
+msgstr "Opbrengste die resultaat van die vermeerdering van die numeriese waardes van die gespesifiseerde veld in die rekords wat voldoen aan die kriteria. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Opgawes die monster standaardafwyking van die numeriese waardes van die gespesifiseerde veld in die rekords wat aan die kriteria voldoen. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Opgawes van die standaardafwyking van die numeriese waardes van die gespesifiseerde veld in die rekords wat aan die kriteria voldoen. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Opgawes die som van die numeriese waardes van die gespesifiseerde veld in die rekords wat aan die kriteria voldoen. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Opgawes die monster variansie van die numeriese waardes van die gespesifiseerde veld in die rekords wat aan die kriteria voldoen. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Opgawes die variansie van die numeriese waardes van die gespesifiseerde veld in die rekords wat aan die kriteria voldoen. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest even integer. "
+msgstr "Rondtes van die waarde in grootte tot die naaste heelgetal selfs. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the values are exactly the same, including case, type, etc. "
+msgstr "Opgawes waar indien die waardes is presies dieselfde, met inbegrip van die geval, tik, ens. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns e raised to the value power. "
+msgstr "Returns e geopper om die waarde mag. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns factorial of the value. "
+msgstr "Opbrengste van faktore van die waarde. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value false. "
+msgstr "Opgawes die logiese waarde vals. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the starting position within string2 of the first occurrence of string1 at or after start. If start is omitted, 1 is assumed. "
+msgstr "Opgawes die begin posisie binne string2 van die eerste voorkoms van string1 op of na die begin. As begin uitgelaat is, 1 aanname gemaak word. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the future value of repeated payments of money invested at the given rate for the specified number of periods, with optional present value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Opgawes van die toekomstige waarde van herhaalde betalings van geld belê teen die gegewe prys vir die gespesifiseerde aantal tydperke, met die opsionele huidige waarde (standaard 0) en die tipe van betaling (standaard 0 = aan einde van tydperk, 1 = begin van tydperk). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the row offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. "
+msgstr "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the row offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the hour portion of a time or date/time value. "
+msgstr "Opgawes die uur gedeelte van 'n tyd of die datum / tyd waarde. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Results in true-value if logical-expression is TRUE or non-zero, otherwise results in false-value. "
+msgstr "Resultate in die ware waarde as logies-uitdrukking WAAR is of nie-nul, anders sal die resultate in die vals-waarde. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns a cell or range reference for the specified row and column in the range. If range is 1-dimensional, then only one of rownum or colnum are needed. If range is 2-dimensional and rownum or colnum are zero, a reference to the range of just the specified column or row is returned. You can use the returned reference value in a range, e.g., sum(A1:INDEX(A2:A10,4)). "
+msgstr "Opbrengste van 'n sel of omvang verwysing vir die gekose ry en kolom in die reeks. As reeks is 1-dimensionele, dan is slegs een van rownum of colnum is nodig. As reeks is 2-dimensionele en rownum of colnum is nul, 'n verwysing na die omvang van net die gekose kolom of ry teruggestuur is. Jy kan gebruik maak van die teruggestuur verwysing waarde in 'n reeks, bv, som (A1: WELKOM (A2: A10 4)). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value rounded down to the nearest integer (towards -infinity). "
+msgstr "Opgawes die waarde afgerond tot die naaste heelgetal (na-oneindigheid). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the interest rate at which the cash flows in the range have a net present value of zero. Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "Opgawes die rentekoers waarteen die kontantvloei in die reeks het 'n netto huidige waarde van nul. Gebruik van 'n iteratiewe proses wat # NUM sal terugkeer! fout as dit nie konvergeer. Miskien is daar meer as een moontlike oplossing. Die verskaffing van die opsionele raai waarde kan help waar dit nie gebeur nie konvergeer in sekere situasies of vind 'n oplossing nie (die standaard dink 10% is). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is a reference to a blank cell. "
+msgstr "Opgawes waar as die waarde is 'n verwysing na' n leë sel. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error but not NA. "
+msgstr "Opgawes waar as die waarde is van die tipe fout, maar nie Nvt. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error. "
+msgstr "Returns ware as die waarde is van die tipe fout. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Logical (true/false). "
+msgstr "Returns ware as die waarde is van die tipe Logiese (waar / onwaar). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is the error type NA. "
+msgstr "Opgawes waar as die waarde is die fout tipe Nvt. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is not of type Text. "
+msgstr "Opgawes waar as die waarde is nie van die soort teks. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Number (including logical values). "
+msgstr "Returns ware as die waarde is van die tipe Number (insluitende logiese waardes). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Text. "
+msgstr "Opgawes waar as die waarde is van die soort teks. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value. If count is omitted, 1 is assumed. "
+msgstr "Opgawes van die gespesifiseerde aantal van karakters uit die teks waarde. As Telling uitgelaat is, 1 aanname gemaak word. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of characters in the text value. "
+msgstr "Opgawes van die aantal karakters in die teks waarde. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the natural logarithm of the value. "
+msgstr "Opgawes van die natuurlike logaritme van die waarde. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logarithm of the value using the specified base. "
+msgstr "Opgawes van die logaritme van die waarde van die gebruik van die gespesifiseerde basis. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the base 10 logarithm of the value. "
+msgstr "Opgawes die grondtal 10 logaritme van die waarde. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all uppercase characters converted to lowercase. "
+msgstr "Opgawes van die teks waarde, met al die hoofletters omgeskakel na klein letters. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return position (the first is 1) in that range. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. If rangelookup is -1, act like 1 but the bracket is match>=value. "
+msgstr "Afhangende van die ooreenstemmende waarde vir die gegewe waarde in die reeks en terugkeer posisie (die eerste is 1) in die reeks. As rangelookup is 1 (standaard) en nie 0, ooreenstem indien dit binne die numeriese hakies (ooreenstem <= waarde) in plaas van exact match. As rangelookup is -1, tree op soos 1, maar die haak is 'match> = waarde. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values. "
+msgstr "Opgawes van die maksimum van die numeriese waardes. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the specified position. "
+msgstr "Opgawes van die gespesifiseerde aantal van karakters uit die teks waarde vanaf die gespesifiseerde posisie. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minimum of the numeric values. "
+msgstr "Opgawes die minimum van die numeriese waardes. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minute portion of a time or date/time value. "
+msgstr "Opgawes die minuut gedeelte van 'n tyd of die datum / tyd waarde. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the remainder of the first value divided by the second. "
+msgstr "Opgawes die res van die eerste waarde gedeel deur die tweede. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the month part of a date value. "
+msgstr "Opgawes van die maand deel van 'n datum waarde. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value if it is a numeric value otherwise an error. "
+msgstr "Opgawes die waarde indien dit 'n numeriese waarde wat andersins' n fout. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the #N/A error value which propagates through most operations. "
+msgstr "Opgawes die # N / A fout waarde wat voortgeplant word deur middel van die meeste bedrywighede. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns FALSE if value is true, and TRUE if it is false. "
+msgstr "Returns ONWAAR is as die waarde waar is, en WAAR indien dit vals is. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date/time. "
+msgstr "Gee die huidige datum / tyd. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of periods at which payments invested each period at the given rate with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period) has the given present value. "
+msgstr "Opgawes van die aantal tydperke waarin die betalings belê elke periode op die gegewe koers met opsionele toekomstige waarde (standaard 0) en die tipe van betaling (standaard 0 = aan einde van tydperk, 1 = begin van tydperk) het die gegewe huidige waarde. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the net present value of cash flows (which may be individual values and/or ranges) at the given rate. The flows are positive if income, negative if paid out, and are assumed at the end of each period. "
+msgstr "Opgawes die netto huidige waarde van kontantvloei (wat moontlik individuele waardes en / of bereik word) by die gegewe prys. Die strome is die positiewe as inkomste, negatiewe as uitbetaal, en is veronderstel om die einde van elke tydperk. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest odd integer. "
+msgstr "Rondtes van die waarde in grootte na die naaste onewe getal is. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if any argument is true "
+msgstr "Waar indien enige argument is waar "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "The value 3.1415926... "
+msgstr "Die waarde 3.1415926 ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of each payment that must be invested at the given rate for the specified number of periods to have the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Opgawes van die bedrag van elke betaling wat op die gegewe persentasie van die gespesifiseerde aantal periodes moet belê word om die gespesifiseerde huidige waarde, met opsioneel toekomstige waarde (standaard 0) en die tipe van betaling (standaard 0 = aan einde van tydperk, 1 = begin van tydperk). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the first value raised to the second value power. "
+msgstr "Gee die eerste waarde te verhoog tot die tweede waarde mag. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values. "
+msgstr "Opbrengste die resultaat van die vermeerdering van die numeriese waardes. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with the first letter of each word converted to uppercase and the others to lowercase. "
+msgstr "Opgawes van die teks waarde in die eerste letter van elke woord omskep in hoofletters en die ander na klein letters. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the present value of the given number of payments each invested at the given rate, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Opgawes die huidige waarde van die gespesifiseerde getal van die betalings elke belê teen die gegewe prys, met opsioneel toekomstige waarde (standaard 0) en die tipe van betaling (standaard 0 = aan einde van tydperk, 1 = begin van tydperk). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in degrees into radians. "
+msgstr "Converteert waarde in die grade na radiale. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the rate at which the given number of payments each invested at the given rate has the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "Opgawes die tempo waarteen die gegewe aantal betalings elke belê teen die gegewe prys het die gespesifiseerde huidige waarde, met opsioneel toekomstige waarde (standaard 0) en die tipe van betaling (standaard 0 = aan einde van tydperk, 1 = begin van tydperk). Gebruik van 'n iteratiewe proses wat # NUM sal terugkeer! fout as dit nie konvergeer. Miskien is daar meer as een moontlike oplossing. Die verskaffing van die opsionele raai waarde kan help waar dit nie gebeur nie konvergeer in sekere situasies of vind 'n oplossing nie (die standaard dink 10% is). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the specified number of characters starting from the specified position replaced by text2. "
+msgstr "Returns text1 met die gespesifiseerde aantal van karakters vanaf die gespesifiseerde posisie vervang deur text2. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text repeated the specified number of times. "
+msgstr "Opgawes van die teks herhaal die gespesifiseerde aantal kere. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the end. If count is omitted, 1 is assumed. "
+msgstr "Opgawes van die gespesifiseerde aantal van karakters uit die teks waarde vanaf die einde. As Telling uitgelaat is, 1 aanname gemaak word. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value to the specified number of decimal places. If precision is negative, then round to powers of 10. The default precision is 0 (round to integer). "
+msgstr "Rondtes van die waarde van die gespesifiseerde aantal desimale plekke. As akkuraatheid negatief is, dan rond te magte van 10. Die standaard akkuraatheid is 0 (ronde tot heelgetal). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of rows in the range. "
+msgstr "Opgawes die aantal rye in die reeks. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the second portion of a time or date/time value (truncated to an integer). "
+msgstr "Opbrengste van die tweede gedeelte van 'n tyd of die datum / tyd waarde (kapt om' n heelgetal). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric sine function (value is in radians) "
+msgstr "Trigonometriese sinus funksie (waarde is in radiale) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at each period of time using the straight-line method. "
+msgstr "Opgawes van die bedrag van waardevermindering op elke periode van tyd met behulp van die reguitlyn-metode. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Square root of the value "
+msgstr "Vierkantswortel van die waarde "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values. "
+msgstr "Opgawes die monster standaardafwyking van die numeriese waardes. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values. "
+msgstr "Opgawes die standaardafwyking van die numeriese waardes. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the all occurrences of oldtext replaced by newtext. If occurrence is present, then only that occurrence is replaced. "
+msgstr "Returns text1 met die alle voorkomste van oldtext vervang deur newtext. As voorval teenwoordig is nie, dan net dat die voorkoms vervang is. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Adds the numeric values. The values to the sum function may be ranges in the form similar to A1:B5. "
+msgstr "Voeg die numeriese waardes. Die waardes aan die som-funksie kan bereik, in die vorm soortgelyk aan A1: B5 word. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sums the numeric values of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). If range2 is present, then range1 is tested and the corresponding range2 value is summed. "
+msgstr "Kostes van die numeriese waardes van die selle in die reeks wat aan die kriteria voldoen. Die kriteria kan wees van 'n waarde (' x ', 15, 1 3) of' n toets (> 25). As range2 teenwoordig is nie, dan range1 is getoets en die ooreenstemmende range2 waarde is opgesom. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Depreciation by Sum of Year's Digits method. "
+msgstr "Waardevermindering deur Som van die Jaar se Tydsbeswaarde metode. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value or else a null string. "
+msgstr "Opgawes van die teks waarde of anders 'gelyk is aan nul. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric tangent function (value is in radians) "
+msgstr "Trigonometriese tangens funksie (waarde is in radiale) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the time value given the specified hour, minute, and second. "
+msgstr "Opgawes die tydwaarde gegewe die gespesifiseerde uur, minuut, en die tweede. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date (an integer). Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "Gee die huidige datum ( 'n heelgetal). Let wel: In hierdie program, dag 1 is 31 Desember 1899 en die jaar 1900 is nie 'n skrikkeljaar. Sommige programme gebruik 1 Januarie 1900, soos dag 1 en behandeling van 1900 as 'n skrikkeljaar. In beide gevalle, alhoewel, datums op of na 1 Maart 1900, is dieselfde. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with leading, trailing, and repeated spaces removed. "
+msgstr "Gee die teks waarde met vooraanstaande, sleep, en herhaalde spasies verwyder. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value true. "
+msgstr "Opgawes die logiese waarde waar. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Truncates the value to the specified number of decimal places. If precision is negative, truncate to powers of 10. "
+msgstr "Truncates die waarde van die gespesifiseerde aantal desimale plekke. As akkuraatheid negatief is, afkorten magte van 10. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all lowercase characters converted to uppercase. "
+msgstr "Opgawes van die teks waarde, met al die klein letters omgeskakel in hoofletters. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts the specified text value into a numeric value. Various forms that look like numbers (including digits followed by %, forms that look like dates, etc.) are handled. This may not handle all of the forms accepted by other spreadsheets and may be locale dependent. "
+msgstr "Vat die gespesifiseerde teks waarde in 'n numeriese waarde. Verskillende vorms wat lyk soos getalle (insluitend die syfers gevolg deur '%, vorms wat lyk soos datums, ens) word hanteer. Dit kan hanteer al die vorms word aanvaar deur ander spread nie en kan plaaslike afhanklik is. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values. "
+msgstr "Opgawes die monster variansie van die numeriese waardes. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values. "
+msgstr "Opgawes die variansie van die numeriese waardes. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the column offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match>=value) instead of exact match. "
+msgstr "Afhangende van die ooreenstemmende waarde vir die gegewe waarde in die reeks en die terugkeer van die ooreenstemmende waarde in die sel is verskaf deur die kolom verreken. As rangelookup is 1 (standaard) en nie 0, ooreenstem indien dit binne die numeriese hakies (ooreenstem> = waarde) in plaas van exact match. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of week specified by the date value. If type is 1 (the default), Sunday is day and Saturday is day 7. If type is 2, Monday is day 1 and Sunday is day 7. If type is 3, Monday is day 0 and Sunday is day 6. "
+msgstr "Opbrengste van die dag van die week word bepaal deur die datum waarde. As soort is, is 1 (standaard), Sondag is die dag en Saterdag is 'dag 7. As tipe is 2, Maandag is dag 1 en Sondag is die dag 7. As tipe is 3, Maandag is dag 0 en Sondag is die dag 6. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the year part of a date value. "
+msgstr "Opgawes die jaar deel van 'n datum waarde. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value"
+msgstr "waarde"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value1, value2, ..."
+msgstr "waarde1, value2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "valueX, valueY"
+msgstr "waardeX, valueY"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "index, value1, value2, ..."
+msgstr "indeks, waarde1, value2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range"
+msgstr "reeks"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, criteria"
+msgstr "omvang, kriteria"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "year, month, day"
+msgstr "jaar, maand, dag"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "databaserange, fieldname, criteriarange"
+msgstr "databaserange, fieldname, criteriarange"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period [, factor]"
+msgstr "koste, berge, leeftyd, periode [, faktor]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "string1, string2 [, start]"
+msgstr "string1, string2 [begin]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [pv, [paytype]]"
+msgstr "koers, n, betaling, [pv, [Betaling Type]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, row, [rangelookup]"
+msgstr "waarde, reeks, ry, [rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "logical-expression, true-value, false-value"
+msgstr "logies-uitdrukking, waar-waarde, vals-waarde"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, rownum, colnum"
+msgstr "reeks, rownum, colnum"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, [guess]"
+msgstr "reeks, [dink]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, count"
+msgstr "teks, reken"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, base"
+msgstr "waarde, basis"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, [rangelookup]"
+msgstr "waarde, reeks, [rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, start, length"
+msgstr "teks, die begin van lengte"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, payment, pv, [fv, [paytype]]"
+msgstr "koers, betaling, pv, [fv, [Betaling Type]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, value1, value2, ..."
+msgstr "koers, waarde1, value2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, pv, [fv, [paytype]]"
+msgstr "koers, n, pv, [fv, [Betaling Type]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [fv, [paytype]]"
+msgstr "koers, n, betaling, [fv, [Betaling Type]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "n, payment, pv, [fv, [paytype, [guess]]]"
+msgstr "n, betaling, pv, [fv, [Betaling Type, [dink]]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, start, length, text2"
+msgstr "text1, begin, lengte, text2"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, [precision]"
+msgstr "waarde, [presies]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime"
+msgstr "kos, redding, leeftyd"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period"
+msgstr "kos, redding, leeftyd, periode"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, oldtext, newtext [, occurrence]"
+msgstr "text1, oldtext, newtext [, voorkoms]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range1, criteria [, range2]"
+msgstr "range1, kriteria [, range2]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "hour, minute, second"
+msgstr "uur, minuut, sekonde"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, col, [rangelookup]"
+msgstr "waarde, reeks, kol, [rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date, [type]"
+msgstr "datum, [tipe]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date"
+msgstr "datum"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["all", "stat", "lookup", "datetime", "financial", "test", "math", Text]
+#msgstr ["alle", "stat", "soek", "datetime", "finansiële", "toets", "math", teks]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "All"
+msgstr "Alles"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Statistics"
+msgstr "Statistieke"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Lookup"
+msgstr "Lookup"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Date & Time"
+msgstr "Datum & Tyd"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Financial"
+msgstr "Finansiële"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Test"
+msgstr "Toets"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Math"
+msgstr "Math"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cells to Graph"
+msgstr "Selle te Grafiek"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Graph"
+msgstr "Set Selle Om Grafiek"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph Type"
+msgstr "Grafiek Tipe"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "filter:alpha(opacity=90);opacity:.9;"
+msgstr "filter: alpha (opacity = 90); opaciteit: ,9;"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain"
+msgstr "Plain"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph"
+msgstr "Grafiek"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Pie Chart"
+msgstr "Sirkelgrafiek"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Help"
+msgstr "Help"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal Bar"
+msgstr "Horizontal Bar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical Bar"
+msgstr "Vertikale Bar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Line Chart"
+msgstr "Lyn Chart"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plot Points"
+msgstr "Plot punte"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown range name"
+msgstr "Onbekend omvang naam"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hide Help"
+msgstr "Steek Hulp"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Max "
+msgstr "Max "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Min "
+msgstr "Min "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " OK "
+msgstr " OK "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Cancel]"
+msgstr "[Cancel]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "TRUE"
+msgstr "Waar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "FALSE"
+msgstr "ONWAAR"
+
diff --git a/po/ar.po b/po/ar.po
new file mode 100644
index 0000000..b83e0db
--- /dev/null
+++ b/po/ar.po
@@ -0,0 +1,1478 @@
+# Copyright (C) 2010 THE PACKAGE"S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# olpc user <olpc@localhost.localdomain>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: SocialCalcActivity.activity\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-01-07 14:46+0000\n"
+"PO-Revision-Date: 2010-01-09 21:53+0530\n"
+"Last-Translator: Diksha<dksh.khatri@gmail.com>\n"
+"Language-Team: Hindi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: activity/activity.info:2
+msgid "SocialCalcActivity"
+msgstr "SocialCalcActivity"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:10
+#msgid "t"
+#msgstr "t"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:13
+msgid "Browser not supported. "
+msgstr "متصÙØ­ غير معتمد. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:14
+msgid "Internal SocialCalc error (probably an internal bug):"
+msgstr "الداخلية SocialCalc الخطأ (وربما لعلة داخلية):"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:20
+msgid "Unknown col type item"
+msgstr "غير معرو٠العمود نوع البند"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:21
+msgid "Unknown row type item"
+msgstr "ص٠نوع العنصر المجهول"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:22
+msgid "Unknown line type"
+msgstr "خط نوع غير معروÙ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:28
+msgid "Unknown cell type item"
+msgstr "غير معروÙØ© الخلية نوع البند"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:36
+msgid "Unknown sheet command: "
+msgstr "ورقة مجهولة الأمر : "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:37
+msgid "Unknown set coord command: "
+msgstr "مجموعة coord أمر غير معرو٠: "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:38
+msgid "Unknown command: "
+msgstr "أمر غير معرو٠: "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:42
+msgid "Circular reference to "
+msgstr "بالإشارة إلى التعميم "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:52
+msgid "padding:2px 2px 1px 2px;vertical-align:top;"
+msgstr "الحشو : 2px 2px 1px 2px ؛ الرأسي محاذاة : أعلى ؛"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:53
+msgid "normal normal"
+msgstr "عادي عادي"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:54
+msgid "small"
+msgstr "صغير"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:55
+msgid "Verdana,Arial,Helvetica,sans-serif"
+msgstr "Verdana ØŒ ارييل ØŒ هلÙتيكا ØŒ بلا - الرقيق"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:92
+msgid "Render Context must have a sheet object"
+msgstr "تجعل السياق يجب أن يكون الكائن ورقة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Executing..."
+msgstr "تنÙيذ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Displaying..."
+msgstr "عرض..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Ordering..."
+msgstr "يأمر..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating..."
+msgstr "حساب..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating... Loading Sheet..."
+msgstr "حساب... تحميل ورقة..."
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "doing server function "
+msgstr "تقوم وظيÙØ© الخادم "
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " in cell "
+msgstr "ÙÙŠ الخلية "
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculation start..."
+msgstr "يبدأ حساب..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SUM"
+msgstr "سوم"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Multi-line text: Click icon on right to edit]"
+msgstr "[متعدد سطر النص : انقر على أيقونة على الحق ÙÙŠ تحرير]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function "
+msgstr "وظيÙØ© غير معروÙ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane vertically"
+msgstr "اسحب لتأمين جزء عموديا"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane horizontally"
+msgstr "اسحب لتأمين جزء Ø£Ùقيا"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Center"
+msgstr "مركز محاذاة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Left"
+msgstr "محاذاة إلى اليسار"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Right"
+msgstr "محاذاة إلى اليمين"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Alignment"
+msgstr "المحاذاة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit"
+msgstr "المراجعة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit Trail This Session"
+msgstr "المراجعة تريل هذه الدورة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto"
+msgstr "السيارات"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto Sum"
+msgstr "مجموع السيارات"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto w/ commas"
+msgstr "السيارات Ø« / الÙواصل"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Automatic"
+msgstr "التلقائي"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Background"
+msgstr "خلÙية"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold"
+msgstr "جريئة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold &amp; Italics"
+msgstr "جريئة ومائل"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold Italic"
+msgstr "غامق مائل"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders"
+msgstr "الحدود"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders Off"
+msgstr "خارج الحدود"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders On"
+msgstr "ÙˆÙÙŠ حدود"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom"
+msgstr "أسÙÙ„"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom Border"
+msgstr "أسÙÙ„ الحدود"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CELL SETTINGS"
+msgstr "البطارية الإعدادات"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CSV format"
+msgstr "تنسيق CSV"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cancel"
+msgstr "إلغاء"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Category"
+msgstr "الÙئة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Center"
+msgstr "مركز"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear"
+msgstr "واضح"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear SocialCalc Clipboard"
+msgstr "واضح SocialCalc الحاÙظة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clipboard"
+msgstr "الحاÙظة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Color"
+msgstr "اللون"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Column"
+msgstr "العمود"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Comment"
+msgstr "التعليق"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Copy"
+msgstr "نسخة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Custom"
+msgstr "مخصص"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cut"
+msgstr "قص"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default"
+msgstr "اÙتراضي"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Alignment"
+msgstr "المحاذاة الاÙتراضية"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Column Width"
+msgstr "عرض العمود الاÙتراضي"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Font"
+msgstr "الخط الاÙتراضي"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Format"
+msgstr "الشكل الاÙتراضي"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Padding"
+msgstr "الاÙتراضي البطانة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete"
+msgstr "حذÙ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Column"
+msgstr "حذ٠عمود"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Contents"
+msgstr "حذ٠المحتويات"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Row"
+msgstr "حذ٠صÙ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Description"
+msgstr "الوصÙ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Display Clipboard in"
+msgstr "عرض ÙÙŠ الحاÙظة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Down"
+msgstr "أسÙÙ„"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Edit"
+msgstr "عدل"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Existing Names"
+msgstr "أسماء القائمة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Family"
+msgstr "عائلة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Down"
+msgstr "ملء أسÙÙ„"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Right"
+msgstr "ملء الحق"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Font"
+msgstr "الخط"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Format"
+msgstr "شكل"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula"
+msgstr "الصيغة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Function List"
+msgstr "وظيÙØ© قائمة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Functions"
+msgstr "وظائÙ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Grid"
+msgstr "الشبكة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hidden"
+msgstr "المخÙÙŠ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal"
+msgstr "Ø£Ùقي"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Column"
+msgstr "إدراج عمود"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Row"
+msgstr "إدراج صÙ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Italic"
+msgstr "مائل"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Last Sort"
+msgstr "نوع آخر"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left"
+msgstr "يسار"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left Border"
+msgstr "غادر الحدود"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link"
+msgstr "رابط"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link Input Box"
+msgstr "ربط مربع الإدخال"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "List"
+msgstr "قائمة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Load SocialCalc Clipboard With This"
+msgstr "تحميل SocialCalc الحاÙظة مع هذا"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Major Sort"
+msgstr "Ùرز الميجر"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Manual"
+msgstr "مختصر"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Merge Cells"
+msgstr "دمج الخلايا"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Middle"
+msgstr "المتوسطة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Minor Sort"
+msgstr "ترتيب Ø·ÙÙŠÙØ©"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Insert"
+msgstr "نقل إدراج"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Paste"
+msgstr "تتحرك لصق"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Multi-line Input Box"
+msgstr "متعدد خط مربع الإدخال"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Name"
+msgstr "اسم"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Names"
+msgstr "أسماء"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "No padding"
+msgstr "لا الحشو"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Normal"
+msgstr "عادية"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number"
+msgstr "عدد"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number Horizontal"
+msgstr "عدد Ø£Ùقي"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "OK"
+msgstr "مواÙÙ‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Padding"
+msgstr "الحشو"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Page Name"
+msgstr "الصÙحة الاسم"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste"
+msgstr "لصق"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste Formats"
+msgstr "لصق تنسيقات"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain Text"
+msgstr "نص عادي"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalc"
+msgstr "Recalc"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalculation"
+msgstr "إعادة الحساب"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " Redo"
+msgstr " إعادته"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right"
+msgstr "صحيح"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right Border"
+msgstr "الحق حرس الحدود"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SHEET SETTINGS"
+msgstr "ورقة الإعدادات"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save"
+msgstr "Ø­Ùظ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save to"
+msgstr "لإنقاذ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cell Contents"
+msgstr "تعيين محتويات الخلية"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Sort"
+msgstr "مجموعة الخلايا لترتيب"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Value To"
+msgstr "تعيين القيمة إلى"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set to Link format"
+msgstr "لتعيين الشكل وصله"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set/Clear Move From"
+msgstr "مجموعة / مسح الانتقال من"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Cell Settings"
+msgstr "وتظهر خلية اعدادات"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Sheet Settings"
+msgstr "وتظهر ورقة الضبط"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show in new browser window"
+msgstr "وتظهر ÙÙŠ ناÙذة جديدة للمتصÙØ­"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Size"
+msgstr "حجم"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SocialCalc-save format"
+msgstr "SocialCalc - Ø­Ùظ تنسيق"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort"
+msgstr "النوع"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort Cells"
+msgstr "خلايا ترتيب"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Swap Colors"
+msgstr "تبديل الألوان"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Tab-delimited format"
+msgstr "تنسيق المÙصول"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text"
+msgstr "النص"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text Horizontal"
+msgstr "نص Ø£Ùقي"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "This is a<br>sample"
+msgstr "هذا هو<br>عينة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top"
+msgstr "أعلى"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top Border"
+msgstr "أعلى الحدود"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "UNDONE STEPS"
+msgstr "التراجع عن الخطوات"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "URL"
+msgstr "العنوان"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Undo"
+msgstr "التراجع"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unmerge Cells"
+msgstr "إلغاء دمجها خلايا"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Up"
+msgstr "Ùوق"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Value"
+msgstr "القيمة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical"
+msgstr "عمودي"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Workspace"
+msgstr "مساحة العمل"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[New]"
+msgstr "[جديد]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[None]"
+msgstr "[لا يوجد]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[select range]"
+msgstr "[مجموعة حدد]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
+#msgstr [ "الأحد" ، "الاثنين" ، "الثلاثاء" ، "الأربعاء" ، "الخميس" ، "الجمعة" ، "السبت"]
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
+#msgstr [ "الشمس" ، "الاثنين" ، "الثلاثاء" ، "الأربعاء" ، "خميس" ، "الجمعة" ، "السبت"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["January", "February", "March", "April", "May", "June", "July", "August", "September","October", "November", "December"]
+#msgstr [ "يناير" ØŒ "Ùبراير" ØŒ "مارس" ØŒ "نيسان" ØŒ "مايو" ØŒ "يونيو" ØŒ "يوليو" ØŒ "أغسطس" ØŒ "سبتمبر" ØŒ "اكتوبر" ØŒ "نوÙمبر" ØŒ "ديسمبر"]
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+#msgstr [ "يناير" ØŒ "Ùبراير" ØŒ "مارس" ØŒ "أبريل" ØŒ "مايو" ØŒ "يونيو" ØŒ "يوليو" ØŒ "أغسطس" ØŒ "سبتمبر" ØŒ "أكتوبر" ØŒ "نوÙمبر" ØŒ "ديسمبر"]
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "AM"
+#msgstr "ص"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "A"
+#msgstr "Ø£"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "PM"
+#msgstr "Ù…"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "P"
+#msgstr "Ù"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed number exponent"
+msgstr "تشكلت بشكل غير سليم الأس عدد"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unexpected character in formula"
+msgstr "حر٠غير متوقع ÙÙŠ صيغة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed string"
+msgstr "تشكلت بشكل غير سليم السلسلة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed special value"
+msgstr "تشكلت بشكل غير سليم قيمة خاصة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula (two operators inappropriately in a row)"
+msgstr "خطأ ÙÙŠ صيغة (شركتي غير لائق على التوالي)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing open parenthesis in list with comma(s)."
+msgstr "Ù…Ùقود قوس Ù…Ùتوح ÙÙŠ قائمة مع Ùاصلة (Ù‚)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Closing parenthesis without open parenthesis. "
+msgstr "قوس دون Ùتح قوس. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing close parenthesis."
+msgstr "Ù…Ùقود قوس قريبة."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing operand."
+msgstr "المعامل ÙÙŠ عداد المÙقودين."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula."
+msgstr "خطأ ÙÙŠ الصيغة."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error value in formula"
+msgstr "قيمة الخطأ ÙÙŠ الصيغة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula resulting in bad value"
+msgstr "خطأ ÙÙŠ الصيغة الناتج ÙÙŠ قيمة سيئة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in range value:"
+msgstr "النتائج ÙÙŠ الÙورمولا وقيمة مجموعة :"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in an bad numeric value"
+msgstr "صيغة النتائج ÙÙŠ قيمة رقمية سيئة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Numeric overflow"
+msgstr "Numeric overflow"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet unavailable:"
+msgstr "ورقة غير متوÙرة :"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cell reference missing when expected."
+msgstr "مرجع الخلية ÙÙŠ عداد المÙقودين عندما المتوقع."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet name missing when expected."
+msgstr "اسم الورقة ÙÙŠ عداد المÙقودين عندما المتوقع."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Circular name reference to name"
+msgstr "التعميم اسم الإشارة إلى اسم"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown name"
+msgstr "اسم غير معروÙ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Incorrect arguments to function"
+msgstr "حجج غير صحيحة إلى وظيÙØ©"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function"
+msgstr "وظيÙØ© غير معروÙ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LN argument must be greater than 0"
+msgstr "0 قانون الجنسية حجة يجب أن تكون أكبر من"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG10 argument must be greater than 0"
+msgstr "LOG10 حجة يجب أن تكون أكبر من 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG second argument must be numeric greater than 0"
+msgstr "0 دخو الحجة الثانية يجب أن تكون رقمية أكبر من"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG first argument must be greater than 0"
+msgstr "0 دخو الحجة الأولى يجب أن تكون أكبر من"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "ROUND second argument must be numeric"
+msgstr "جولة الحجة الثانية يجب أن تكون رقمية"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "DDB life must be greater than 1"
+msgstr "DDB الحياة يجب أن تكون أكبر من 1"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SLN life must be greater than 1"
+msgstr "1 شركة النيكل الحياة يجب أن تكون أكبر من"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Absolute value function. "
+msgstr "القيمة المطلقة وظيÙØ©. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arccosine function. "
+msgstr "مثلثي الدالة قوس جيب تمام الزاوية. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if all arguments are true. "
+msgstr "إذا كان صحيحا كل الحجج صحيحا. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arcsine function. "
+msgstr "مثلثي دالة جيب الزاوية القوسي. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arctan function. "
+msgstr "مثلثي ظل الزاوية القوسي وظيÙØ©. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arc tangent function (result is in radians). "
+msgstr "مثلثي قوس دالة الظل (النتيجة هي بالراديان). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values. "
+msgstr "متوسطات القيم. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value specified by the index. The values may be ranges of cells. "
+msgstr "إرجاع القيمة التي يحددها المؤشر. قيم قد تكون نطاقات من الخلايا. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of columns in the range. "
+msgstr "إرجاع عدد الأعمدة ÙÙŠ النطاق. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric cosine function (value is in radians). "
+msgstr "مثلثي جيب التمام وظيÙØ© (القيمة هي ÙÙŠ راديان). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error. "
+msgstr "بحساب عدد من القيم الرقمية ØŒ وليس Ùارغا ØŒ والنص ØŒ أو الخطأ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values. "
+msgstr "بحساب عدد من القيم غير Ùارغة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of blank values. (Note: '' is not blank.) "
+msgstr "بحساب عدد من القيم الÙارغة. (ملاحظة : ''ليست Ùارغة.) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of number of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). "
+msgstr "بحساب عدد من عدد من الخلايا ÙÙŠ النطاق التي تÙÙŠ بالمعايير. معايير قد تكون قيمة ( 'س' ØŒ 15 ØŒ 1 +3) أو اختبار (> 25). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the appropriate date value given numbers for year, month, and day. For example: DATE(2006,2,1) for February 1, 2006. Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "إرجاع القيمة المناسبة تاريخ معين لأرقام السنة والشهر واليوم. على سبيل المثال : التاريخ (2006ØŒ2ØŒ1) ÙÙŠ شباط / Ùبراير 1 ØŒ 2006. ملاحظة : ÙÙŠ هذا البرنامج ØŒ 1 اليوم هو 31 ديسمبر 1899 وسنة 1900 ليست سنة كبيسة. استخدام بعض البرامج 1 يناير 1900 ØŒ ويوم 1 وعلاج 1900 سنة كبيسة. ÙÙŠ كلتا الحالتين ØŒ على الرغم من والتواريخ ÙÙŠ أو بعد 1 مارس 1900 ØŒ هي Ù†Ùسها. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values in the specified field in records that meet the criteria. "
+msgstr "متوسطات القيم ÙÙŠ الحقل المحدد ÙÙŠ السجلات التي تÙÙŠ بالمعايير. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of month for a date value. "
+msgstr "يعود اليوم من شهر لقيمة تاريخ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error, in the specified field in records that meet the criteria. "
+msgstr "بحساب عدد من القيم الرقمية ØŒ وليس Ùارغا ØŒ والنص ØŒ أو خطأ ØŒ ÙÙŠ هذا المجالالمحدد ÙÙŠ السجلات التي تÙÙŠ بالمعايير. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values in the specified field in records that meet the criteria. "
+msgstr "بحساب عدد من القيم غير Ùارغة ÙÙŠ الحقل المحدد ÙÙŠ السجلات التيتÙÙŠ بالمعايير. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at the given period of time (the default factor is 2 for double-declining balance). "
+msgstr "بإرجاع مبلغ الاستهلاك ÙÙŠ Ùترة زمنية معينة (عامل الاÙتراضي هو 2 لالمتناقص المزدوج). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in radians into degrees. "
+msgstr "تحويل القيمة ÙÙŠ التقدير الدائري إلى درجات. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value of the specified field in the single record that meets the criteria. "
+msgstr "إرجاع قيمة الحقل المحدد ÙÙŠ سجل واحد ÙŠÙÙŠ المعايير. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "إرجاع الحد الأقصى للقيم رقمية ÙÙŠ الحقل المحدد ÙÙŠ السجلات التي تÙÙŠ بالمعايير. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values in the specified field in records that meet the criteria. "
+msgstr "بإرجاع نتيجة ضرب القيم الرقمية ÙÙŠ المجال المحدد ÙÙŠ السجلات التي تÙÙŠ بالمعايير. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "إرجاع نموذج الانحرا٠المعياري للقيم رقمية ÙÙŠ الحقل المحدد ÙÙŠ السجلات التي تÙÙŠ بالمعايير. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "بإرجاع الانحرا٠المعياري للقيم رقمية ÙÙŠ الحقل المحدد ÙÙŠ السجلات التي تÙÙŠ بالمعايير. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "إرجاع مجموع القيم الرقمية ÙÙŠ المجال المحدد ÙÙŠ السجلات التي تÙÙŠ بالمعايير. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "يعود التباين عينة من القيم الرقمية ÙÙŠ المجال المحدد ÙÙŠ السجلات التي تÙÙŠ بالمعايير. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "يعود هذا الÙرق ÙÙŠ القيم الرقمية ÙÙŠ المجال المحدد ÙÙŠ السجلات التي تÙÙŠ بالمعايير. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest even integer. "
+msgstr "جولات قيمة ما يصل حجمها إلى أقرب رقم صحيح زوجي. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the values are exactly the same, including case, type, etc. "
+msgstr "العودة الحقيقية إذا كانت القيم هي Ù†Ùسها تماما ØŒ بما ÙÙŠ ذلك الحالة ØŒ اكتب ØŒ الخ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns e raised to the value power. "
+msgstr "Ù‡ يعود مرÙوع إلى قوة قيمة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns factorial of the value. "
+msgstr "إرجاع مضروب من حيث القيمة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value false. "
+msgstr "إرجاع قيمة منطقية كاذبة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the starting position within string2 of the first occurrence of string1 at or after start. If start is omitted, 1 is assumed. "
+msgstr "ترجع نقطة البداية ضمن string2 من التواجد الأول string1 ÙÙŠ أو بعد بدء. إذا بدء محذوÙا ØŒ ÙŠÙترض 1. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the future value of repeated payments of money invested at the given rate for the specified number of periods, with optional present value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "إرجاع القيمة المستقبلية للمدÙوعات المتكررة من الأموال المستثمرة ÙÙŠ معدل معين لعدد محدد من الÙترات ØŒ مع القيمة الحالية اختياري (الاÙتراضي 0) ونوع الدÙع (الاÙتراضي = 0 ÙÙŠ نهاية الÙترة ØŒ 1 = بداية الÙترة). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the row offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. "
+msgstr "ابحث عن قيمة مطابقة لقيمة معينة ÙÙŠ نطاق وإرجاع القيمة المناظرة ÙÙŠ الخلية التي يحددها الص٠تعويض. إذا rangelookup هو 1 (الاÙتراضي) وليس 0 ØŒ المباراة اذا وضعت بين قوسين الرقمية (مباراة <= القيمة) بدلا من تطابق تام. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the hour portion of a time or date/time value. "
+msgstr "إرجاع ساعة جزء من الوقت أو قيمة تاريخ / وقت. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Results in true-value if logical-expression is TRUE or non-zero, otherwise results in false-value. "
+msgstr "النتائج الحقيقية ÙÙŠ القيمة إذا كان من المنطقي ÙÙŠ التعبير صحيحا أو غير الصÙر ØŒ وإلا Ùإن النتائج ÙÙŠ قيمة كاذبة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns a cell or range reference for the specified row and column in the range. If range is 1-dimensional, then only one of rownum or colnum are needed. If range is 2-dimensional and rownum or colnum are zero, a reference to the range of just the specified column or row is returned. You can use the returned reference value in a range, e.g., sum(A1:INDEX(A2:A10,4)). "
+msgstr "عودة خلية أو نطاق إشارة للص٠المحدد والأعمدة ÙÙŠ النطاق. إذا كان النطاق هو 1 الأبعاد ØŒ ثم واحدة Ùقط من rownum أو colnum مطلوبة. إذا كان النطاق هو 2 الأبعاد Ùˆrownum أو colnum هي صÙر ØŒ ÙÙŠ اشارة الى مجموعة من مجرد العمود المحدد أو يتم إرجاع صÙ. يمكنك استخدام عاد القيمة المرجعية ÙÙŠ مجموعة ØŒ على سبيل المثال ØŒ مبلغ (A1 : الرئيسية (A2 : A10 ØŒ 4)). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value rounded down to the nearest integer (towards -infinity). "
+msgstr "إرجاع القيمة تقريبه نزولا إلى أقرب عدد صحيح (نحو - اللانهاية). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the interest rate at which the cash flows in the range have a net present value of zero. Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "إرجاع معدل الÙائدة الذي التدÙقات النقدية ÙÙŠ مجموعة لديها صاÙÙŠ القيمة الحالية لصÙر. يستخدم عملية تكرارية ØŒ سيعود # ارقام! الخطأ إذا كان لا تتلاقى. قد يكون هناك أكثر من حل واحد ممكن. توÙير قيمة تخمين اختياري قد يساعد ÙÙŠ حالات معينة ØŒ حيث أنها لا تتلاقى أو يجد حلا غير مناسب (تخمين الاÙتراضي هو 10 Ùª). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is a reference to a blank cell. "
+msgstr "العودة الحقيقية إذا كانت القيمة هي إشارة إلى خلية Ùارغة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error but not NA. "
+msgstr "العودة الحقيقية إذا كانت القيمة هي نوع من الخطأ ولكن ليس متاح. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error. "
+msgstr "العودة الحقيقية إذا كانت القيمة هي من النوع الخطأ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Logical (true/false). "
+msgstr "العودة الحقيقية إذا كانت القيمة هي من النوع المنطقي (صح / خطأ). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is the error type NA. "
+msgstr "العودة الحقيقية إذا كانت القيمة هو نوع الخطأ غير متاح. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is not of type Text. "
+msgstr "العودة الحقيقية إذا كانت القيمة هي ليست من نوع النص. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Number (including logical values). "
+msgstr "العودة الحقيقية إذا كانت قيمة من نوع رقم (بما ÙÙŠ ذلك القيم المنطقية). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Text. "
+msgstr "العودة الحقيقية إذا كانت القيمة هي من نوع النص. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value. If count is omitted, 1 is assumed. "
+msgstr "إرجاع عدد محدد من الأحر٠من قيمة النص. إذا عد محذوÙا ØŒ ÙŠÙترض 1. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of characters in the text value. "
+msgstr "إرجاع عدد الأحر٠ÙÙŠ قيمة النص. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the natural logarithm of the value. "
+msgstr "إرجاع اللوغاريتم الطبيعي للقيمة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logarithm of the value using the specified base. "
+msgstr "عودة لوغاريتم القيمة باستخدام قاعدة محددة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the base 10 logarithm of the value. "
+msgstr "إرجاع 10 قاعدة لوغاريتم القيمة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all uppercase characters converted to lowercase. "
+msgstr "ترجع قيمة النص مع كاÙØ© الأحر٠الكبيرة إلى أحر٠صغيرة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return position (the first is 1) in that range. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. If rangelookup is -1, act like 1 but the bracket is match>=value. "
+msgstr "ابحث عن قيمة مطابقة لقيمة معينة ÙÙŠ موق٠طائÙØ© والعودة (لأول مرة هو 1) ÙÙŠ هذا النطاق. إذا rangelookup هو 1 (الاÙتراضي) وليس 0 ØŒ المباراة اذا وضعت بين قوسين الرقمية (مباراة <= القيمة) بدلا من تطابق تام. إذا rangelookup هو -1 ØŒ 1 ولكن تتصر٠مثل قوس هي المباراة> = القيمة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values. "
+msgstr "إرجاع الحد الأقصى للقيم رقمية. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the specified position. "
+msgstr "إرجاع عدد محدد من الأحر٠من قيمة النص بدءا من الموضع المحدد. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minimum of the numeric values. "
+msgstr "إرجاع الحد الأدنى من القيم الرقمية. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minute portion of a time or date/time value. "
+msgstr "إرجاع جزء دقيقة من الوقت أو التاريخ / قيمة الوقت. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the remainder of the first value divided by the second. "
+msgstr "إرجاع ما تبقى من القيمة الأولى مقسوما على الثانية. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the month part of a date value. "
+msgstr "إرجاع جزء الشهر من قيمة التاريخ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value if it is a numeric value otherwise an error. "
+msgstr "إرجاع القيمة إذا كان هو قيمة رقمية خلا٠ذلك خطأ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the #N/A error value which propagates through most operations. "
+msgstr "بإرجاع # ن / قيمة الخطأ التي تنتشر من خلال عمليات أكثر. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns FALSE if value is true, and TRUE if it is false. "
+msgstr "إذا كانت قيمة العائدات كاذبة صحيح ، وصحيح إذا كان باطلا. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date/time. "
+msgstr "ترجع التاريخ الحالي / الساعة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of periods at which payments invested each period at the given rate with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period) has the given present value. "
+msgstr "إرجاع عدد Ùترات المدÙوعات التي استثمرت ÙÙŠ كل Ùترة على سعر معين مع القيمة المستقبلية اختياري (الاÙتراضي 0) ونوع الدÙع (الاÙتراضي = 0 ÙÙŠ نهاية الÙترة ØŒ 1 = بداية الÙترة) والقيمة المعطاة حاليا. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the net present value of cash flows (which may be individual values and/or ranges) at the given rate. The flows are positive if income, negative if paid out, and are assumed at the end of each period. "
+msgstr "إرجاع صاÙÙŠ القيمة الحالية للتدÙقات النقدية (التي قد تكون القيم الÙردية Ùˆ / أو نطاقات) بسعر معين. تدÙقات إيجابية إذا الدخل ØŒ وسلبية اذا دÙعت ØŒ ويÙترض ÙÙŠ نهاية كل Ùترة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest odd integer. "
+msgstr "جولات قيمة ما يصل حجمها إلى أقرب عدد صحيح ونيÙ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if any argument is true "
+msgstr "صحيح إذا كان أي وسيطة غير صحيح "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "The value 3.1415926... "
+msgstr "القيمة 3.1415926... "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of each payment that must be invested at the given rate for the specified number of periods to have the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "إرجاع المبلغ الذي دÙع كل ذلك يجب أن تستثمر ÙÙŠ معدل معين لعدد محدد من الÙترات ان القيمة المحددة الحالية ØŒ مع القيمة المستقبلية اختياري (الاÙتراضي 0) ونوع الدÙع (الاÙتراضي = 0 ÙÙŠ نهاية الÙترة ØŒ 1 = بداية الÙترة). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the first value raised to the second value power. "
+msgstr "إرجاع القيمة الأولى التي تثار ÙÙŠ السلطة الثانية القيمة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values. "
+msgstr "بإرجاع نتيجة ضرب قيم رقمية. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with the first letter of each word converted to uppercase and the others to lowercase. "
+msgstr "ترجع قيمة النص مع أول حر٠من كل كلمة وتحويلها إلى أحر٠كبيرة وصغيرة إلى الآخرين. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the present value of the given number of payments each invested at the given rate, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "إرجاع القيمة الحالية لعدد معين من المبالغ المستثمرة ÙÙŠ كل من سعر معين ØŒ مع القيمة المستقبلية اختياري (الاÙتراضي 0) ونوع الدÙع (الاÙتراضي = 0 ÙÙŠ نهاية الÙترة ØŒ 1 = بداية الÙترة). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in degrees into radians. "
+msgstr "تحويل القيمة ÙÙŠ درجات الى راديان. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the rate at which the given number of payments each invested at the given rate has the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "عودة المعدل الذي لعدد معين من المبالغ المستثمرة ÙÙŠ كل من معدل معين قد القيمة المحددة الحالية ØŒ مع القيمة المستقبلية اختياري (الاÙتراضي 0) ونوع الدÙع (الاÙتراضي = 0 ÙÙŠ نهاية الÙترة ØŒ 1 = بداية الÙترة). يستخدم عملية تكرارية ØŒ سيعود # ارقام! الخطأ إذا كان لا تتلاقى. قد يكون هناك أكثر من حل واحد ممكن. توÙير قيمة تخمين اختياري قد يساعد ÙÙŠ حالات معينة ØŒ حيث أنها لا تتلاقى أو يجد حلا غير مناسب (تخمين الاÙتراضي هو 10 Ùª). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the specified number of characters starting from the specified position replaced by text2. "
+msgstr "عودة text1 مع عدد محدد من الحرو٠ابتداء من الموضع المحدد استبداله text2. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text repeated the specified number of times. "
+msgstr "بإرجاع النص المتكرر ÙÙŠ عدد محدد من المرات. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the end. If count is omitted, 1 is assumed. "
+msgstr "إرجاع عدد محدد من الأحر٠من قيمة النص ابتداء من نهاية المباراة. إذا عد محذوÙا ØŒ ÙŠÙترض 1. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value to the specified number of decimal places. If precision is negative, then round to powers of 10. The default precision is 0 (round to integer). "
+msgstr "جولات القيمة إلى عدد محدد من المنازل العشرية. إذا دقة السلبية ØŒ ثم جولة لقوى 10. الدقة الاÙتراضية هي 0 (جولة لعدد صحيح). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of rows in the range. "
+msgstr "إرجاع عدد الصÙÙˆÙ ÙÙŠ هذه المجموعة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the second portion of a time or date/time value (truncated to an integer). "
+msgstr "يعود الجزء الثاني من الوقت أو التاريخ / القيمة الزمنية (اقتطاع إلى عدد صحيح). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric sine function (value is in radians) "
+msgstr "مثلثي دالة جيبية (القيمة هي ÙÙŠ راديان) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at each period of time using the straight-line method. "
+msgstr "بإرجاع مبلغ الاستهلاك ÙÙŠ كل Ùترة من الزمن باستخدام الأسلوب خط مستقيم. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Square root of the value "
+msgstr "الجذر التربيعي للقيمة "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values. "
+msgstr "إرجاع نموذج الانحرا٠المعياري للقيم رقمية. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values. "
+msgstr "بإرجاع الانحرا٠المعياري للقيم رقمية. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the all occurrences of oldtext replaced by newtext. If occurrence is present, then only that occurrence is replaced. "
+msgstr "عودة text1 مع تواجد جميع oldtext استبداله newtext. إذا حدث هو الحاضر ، إلا أن حدوث ذلك يتم استبداله. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Adds the numeric values. The values to the sum function may be ranges in the form similar to A1:B5. "
+msgstr "ويضي٠القيم الرقمية. القيم إلى وظيÙØ© يمكن أن يتراوح المبلغ ÙÙŠ شكل مماثل Ù„A1 : B5. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sums the numeric values of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). If range2 is present, then range1 is tested and the corresponding range2 value is summed. "
+msgstr "مبالغ القيم الرقمية من الخلايا ÙÙŠ النطاق التي تÙÙŠ بالمعايير. معايير قد تكون قيمة ( 'س' ØŒ 15 ØŒ 1 +3) أو اختبار (> 25). range2 إذا كان موجودا ØŒ ثم range1 هو اختبار والمقابلة range2 قيمة تتلخص. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Depreciation by Sum of Year's Digits method. "
+msgstr "الاستهلاك من مجموع أرقام السنة الأسلوب. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value or else a null string. "
+msgstr "بإرجاع قيمة النص أو آخر سلسلة Ùارغة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric tangent function (value is in radians) "
+msgstr "مثلثي دالة الظل (القيمة هي ÙÙŠ راديان) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the time value given the specified hour, minute, and second. "
+msgstr "إرجاع قيمة الوقت نظرا لتأخر الوقت المحدد والدقيقة والثانية. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date (an integer). Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "ترجع التاريخ الحالي (عدد صحيح). ملاحظة : ÙÙŠ هذا البرنامج ØŒ 1 اليوم هو 31 ديسمبر 1899 وسنة 1900 ليست سنة كبيسة. استخدام بعض البرامج 1 يناير 1900 ØŒ ويوم 1 وعلاج 1900 سنة كبيسة. ÙÙŠ كلتا الحالتين ØŒ على الرغم من والتواريخ ÙÙŠ أو بعد 1 مارس 1900 ØŒ هي Ù†Ùسها. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with leading, trailing, and repeated spaces removed. "
+msgstr "ترجع قيمة النص مع الرائد ، والملاحقات ، وأزيلت مساحات المتكررة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value true. "
+msgstr "إرجاع قيمة منطقية صحيحة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Truncates the value to the specified number of decimal places. If precision is negative, truncate to powers of 10. "
+msgstr "باقتطاع قيمة لعدد محدد من المنازل العشرية. إذا دقة السلبية ، واقتطاع لقوى 10. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all lowercase characters converted to uppercase. "
+msgstr "ترجع قيمة النص مع جميع أحر٠صغيرة تحويلها إلى أحر٠كبيرة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts the specified text value into a numeric value. Various forms that look like numbers (including digits followed by %, forms that look like dates, etc.) are handled. This may not handle all of the forms accepted by other spreadsheets and may be locale dependent. "
+msgstr "تحويل النص المحدد القيمة إلى قيمة رقمية. الأشكال المختلÙØ© التي تبدو مثل الأرقام (بما ÙÙŠ ذلك أرقام تليها Ùª ØŒ والأشكال التي تبدو مثل التواريخ ØŒ الخ) يتم معالجتها. هذا لا يجوز التعامل مع كاÙØ© النماذج التي قبلتها جداول البيانات الأخرى ØŒ ويمكن أن تعتمد على اللغة. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values. "
+msgstr "يعود التباين عينة من قيم رقمية. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values. "
+msgstr "يعود هذا الÙرق ÙÙŠ القيم الرقمية. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the column offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match>=value) instead of exact match. "
+msgstr "ابحث عن قيمة مطابقة لقيمة معينة ÙÙŠ نطاق وإرجاع القيمة المناظرة ÙÙŠ الخلية التي يحددها العمود تعويض. إذا rangelookup هو 1 (الاÙتراضي) وليس 0 ØŒ المباراة اذا وضعت بين قوسين الرقمية (مباراة> = القيمة) بدلا من تطابق تام. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of week specified by the date value. If type is 1 (the default), Sunday is day and Saturday is day 7. If type is 2, Monday is day 1 and Sunday is day 7. If type is 3, Monday is day 0 and Sunday is day 6. "
+msgstr "يعود اليوم من الاسبوع تحددها قيمة التاريخ. إذا ما هو نوع 1 (الاÙتراضي) ØŒ ويوم الاحد هو يوم السبت هو يوم 7. إذا ما هو نوع 2 ØŒ ويوم الاثنين هو يوم 1 ويوم الاحد هو يوم 7. إذا كان النوع هو 3 ØŒ ويوم الاثنين هو اليوم 0 ويوم الاحد هو يوم 6. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the year part of a date value. "
+msgstr "يعود الجزء العام من قيمة التاريخ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value"
+msgstr "القيمة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value1, value2, ..."
+msgstr "value1 ، value2 ،..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "valueX, valueY"
+msgstr "valueX, valueY"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "index, value1, value2, ..."
+msgstr "مؤشر ، value1 ، value2 ،..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range"
+msgstr "نطاق"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, criteria"
+msgstr "نطاق ، معايير"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "year, month, day"
+msgstr "السنة ، الشهر ، اليوم"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "databaserange, fieldname, criteriarange"
+msgstr "databaserange ، fieldname ، criteriarange"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period [, factor]"
+msgstr "تكلÙØ© ØŒ تعويض ØŒ عمر ØŒ Ùترة ØŒ [عامل]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "string1, string2 [, start]"
+msgstr "string1 ØŒ string2 [ØŒ اضاÙØ©]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [pv, [paytype]]"
+msgstr "معدل ØŒ Ù† ØŒ والدÙع ØŒ [الÙلطاضوئية ØŒ [paytype]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, row, [rangelookup]"
+msgstr "القيمة ، والمدى ، والص٠، [rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "logical-expression, true-value, false-value"
+msgstr "منطقية التعبير ØŒ وذات قيمة حقيقية أو زائÙØ© القيمة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, rownum, colnum"
+msgstr "ØŒ rownum ØŒ colnumطائÙØ© ØŒ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, [guess]"
+msgstr "مجموعة ، [تخمين]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, count"
+msgstr "النص ، والاعتماد"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, base"
+msgstr "القيمة ، وقاعدة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, [rangelookup]"
+msgstr "القيمة ، مجموعة ، [rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, start, length"
+msgstr "النص ، بداية ، وطول"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, payment, pv, [fv, [paytype]]"
+msgstr "معدل ودÙع الرسوم والكهروضوئية ØŒ [Ù. Ù ØŒ [paytype]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, value1, value2, ..."
+msgstr "معدل ، value1 ، value2 ،..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, pv, [fv, [paytype]]"
+msgstr "معدل ØŒ Ù† ØŒ الكهروضوئية ØŒ [Ù. Ù ØŒ [paytype]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [fv, [paytype]]"
+msgstr "معدل ØŒ Ù† ØŒ والدÙع ØŒ [Ù. Ù ØŒ [paytype]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "n, payment, pv, [fv, [paytype, [guess]]]"
+msgstr "Ù† ØŒ والدÙع ØŒ الكهروضوئية ØŒ [Ù. Ù ØŒ [paytype ØŒ [تخمين]]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, start, length, text2"
+msgstr " ، بداية ، وطولها ، text2text1"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, [precision]"
+msgstr "القيمة ، [دقيقة]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime"
+msgstr "تكلÙØ© ØŒ تعويض ØŒ عمر"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period"
+msgstr "تكلÙØ© ØŒ تعويض ØŒ عمر ØŒ Ùترة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, oldtext, newtext [, occurrence]"
+msgstr "text1 ، oldtext ، newtext [، حدوث]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range1, criteria [, range2]"
+msgstr "range1 ، ومعايير [، range2]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "hour, minute, second"
+msgstr "الساعة ، الدقيقة ، الثانية"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, col, [rangelookup]"
+msgstr "القيمة ØŒ وطائÙØ© ØŒ العمود ØŒ [rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date, [type]"
+msgstr "حتى الآن ، [نوع]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date"
+msgstr "تاريخ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["all", "stat", "lookup", "datetime", "financial", "test", "math", Text]
+#msgstr [ "جميع" ، "القانون الأساسي" ، "بحث" ، "وقت" ، "المالية" ، "اختبار" ، "الرياضيات" ، نص]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "All"
+msgstr "الكل"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Statistics"
+msgstr "إحصاءات"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Lookup"
+msgstr "بحث"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Date & Time"
+msgstr "التاريخ والوقت"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Financial"
+msgstr "المالية"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Test"
+msgstr "اختبار"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Math"
+msgstr "الرياضيات"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cells to Graph"
+msgstr "الخلايا إلى الرسم البياني"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Graph"
+msgstr "مجموعة الخلايا إلى الرسم البياني"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph Type"
+msgstr "نوع الرسم البياني"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "filter:alpha(opacity=90);opacity:.9;"
+msgstr "Ùلتر : ألÙا (عتامة = 90) Ø› التعتيم :.9 Ø›"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain"
+msgstr "سهل"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph"
+msgstr "الرسم البياني"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Pie Chart"
+msgstr "Ùطيرة الرسم البياني"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Help"
+msgstr "مساعدة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal Bar"
+msgstr "العقلة"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical Bar"
+msgstr "الرأسي بار"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Line Chart"
+msgstr "خط الرسم البياني"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plot Points"
+msgstr "مؤامرة النقاط"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown range name"
+msgstr "مجموعة مجهولة الاسم"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hide Help"
+msgstr "إخÙاء التعليمات"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Max "
+msgstr "ماكس "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Min "
+msgstr "دقيقة "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " OK "
+msgstr " مواÙÙ‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Cancel]"
+msgstr "[إلغاء]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "TRUE"
+msgstr "الحقيقية"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "FALSE"
+msgstr "كاذبة"
+
diff --git a/po/de.po b/po/de.po
new file mode 100644
index 0000000..2c431e3
--- /dev/null
+++ b/po/de.po
@@ -0,0 +1,1459 @@
+# Copyright (C) 2010 THE PACKAGE"S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# olpc user <olpc@localhost.localdomain>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: SocialCalcActivity.activity\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-01-07 14:46+0000\n"
+"PO-Revision-Date: 2010-01-09 21:53+0530\n"
+"Last-Translator: Diksha<dksh.khatri@gmail.com>\n"
+"Language-Team: Hindi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: activity/activity.info:2
+msgid "SocialCalcActivity"
+msgstr "SocialCalcActivity"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:10
+#msgid "t"
+#msgstr "t"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:13
+msgid "Browser not supported. "
+msgstr "Browser nicht unterstützt."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:14
+msgid "Internal SocialCalc error (probably an internal bug):"
+msgstr "Interne SocialCalc Fehler (wahrscheinlich ein interner Fehler):"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:20
+msgid "Unknown col type item"
+msgstr "Unbekannt col Typ Artikel"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:21
+msgid "Unknown row type item"
+msgstr "Unbekannt Zeilentyp Artikel"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:22
+msgid "Unknown line type"
+msgstr "Unbekannt Zeilentyp"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:28
+msgid "Unknown cell type item"
+msgstr "Unbekannt Zelltyp Artikel"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:36
+msgid "Unknown sheet command: "
+msgstr "Unbekannt Blatt Befehl ein: "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:37
+msgid "Unknown set coord command: "
+msgstr "Unbekannt eingestellt coord Befehl ein:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:38
+msgid "Unknown command: "
+msgstr "Unbekannter Befehl:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:42
+msgid "Circular reference to "
+msgstr "Circular Verweis auf "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:52
+msgid "padding:2px 2px 1px 2px;vertical-align:top;"
+msgstr "padding: 2px 2px 1px 2px; vertical-align: top;"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:53
+msgid "normal normal"
+msgstr "normal normal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:54
+msgid "small"
+msgstr "klein"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:55
+msgid "Verdana,Arial,Helvetica,sans-serif"
+msgstr "Arial, Helvetica, sans-serif"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:92
+msgid "Render Context must have a sheet object"
+msgstr "Render Kontext muss ein Blatt-Objekt"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Executing..."
+msgstr "Läuft ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Displaying..."
+msgstr "Anzeigen ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Ordering..."
+msgstr "Bestellung ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating..."
+msgstr "Berechnung ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating... Loading Sheet..."
+msgstr "Berechnung ... Loading ... Sheet"
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "doing server function "
+msgstr "Dabei Server-Funktion"
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " in cell "
+msgstr "in Zelle "
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculation start..."
+msgstr "Berechnung zu starten ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SUM"
+msgstr "SUM"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Multi-line text: Click icon on right to edit]"
+msgstr "[Multi-line text: Klicken Sie auf das Symbol auf der rechten Seite zu bearbeiten]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function "
+msgstr "Unbekannte Funktion"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane vertically"
+msgstr "Ziehen Sie die Fenster vertikal Sperre"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane horizontally"
+msgstr "Ziehen Sie die Fenster horizontal lock"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Center"
+msgstr "Zentriert"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Left"
+msgstr "Linksbündig"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Right"
+msgstr "Rechtsbündig"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Alignment"
+msgstr "Alignment"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit"
+msgstr "Audit"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit Trail This Session"
+msgstr "Audit Trail Diese Session"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto"
+msgstr "Auto"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto Sum"
+msgstr "Auto Summe"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto w/ commas"
+msgstr "Auto w / Komma"
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Automatic"
+msgstr "Automatic"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Background"
+msgstr "Hintergrund"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold"
+msgstr "Bold"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold &amp; Italics"
+msgstr "Bold & Kursiv"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold Italic"
+msgstr "Bold Italic"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders"
+msgstr "Borders"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders Off"
+msgstr "Borders Off"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders On"
+msgstr "Grenzt an"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom"
+msgstr "Boden"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom Border"
+msgstr "Bottom Border"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CELL SETTINGS"
+msgstr "CELL EINSTELLUNGEN"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CSV format"
+msgstr "CSV format"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cancel"
+msgstr "Abbrechen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Category"
+msgstr "Kategorie"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Center"
+msgstr "Center"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear"
+msgstr "Klar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear SocialCalc Clipboard"
+msgstr "Frei SocialCalc Zwischenablage"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clipboard"
+msgstr "Zwischenablage"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Color"
+msgstr "Farbe"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Column"
+msgstr "Spalte"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Comment"
+msgstr "Kommentar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Copy"
+msgstr "Kopieren"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Custom"
+msgstr "Brauch"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cut"
+msgstr "Schneiden"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default"
+msgstr "Vorgabe"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Alignment"
+msgstr "Standard-Alignment"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Column Width"
+msgstr "Standard Spaltenbreite"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Font"
+msgstr "Standardschriftart"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Format"
+msgstr "Standard-Format"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Padding"
+msgstr "Standard-Polsterung"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete"
+msgstr "Löschen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Column"
+msgstr "Spalte löschen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Contents"
+msgstr "Inhalt löschen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Row"
+msgstr "Zeile löschen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Description"
+msgstr "Beschreibung"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Display Clipboard in"
+msgstr "Anzeige Zwischenablage in"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Down"
+msgstr "Abwärts"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Edit"
+msgstr "Edit"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Existing Names"
+msgstr "Bestehende Namen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Family"
+msgstr "Familie"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Down"
+msgstr "Fill Down"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Right"
+msgstr "Füllen Sie mit der rechten"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Font"
+msgstr "Font"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Format"
+msgstr "Format"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula"
+msgstr "Formel"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Function List"
+msgstr "Funktionsliste"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Functions"
+msgstr "Funktionen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Grid"
+msgstr "Grid"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hidden"
+msgstr "Hidden"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal"
+msgstr "Horizontal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Column"
+msgstr "Spalte einfügen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Row"
+msgstr "Zeile einfügen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Italic"
+msgstr "Italic"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Last Sort"
+msgstr "Letzte sortieren"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left"
+msgstr "Verließ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left Border"
+msgstr "Left Border"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link"
+msgstr "Link"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link Input Box"
+msgstr "Link Input Box"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "List"
+msgstr "Liste"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Load SocialCalc Clipboard With This"
+msgstr "Load SocialCalc Zwischenablage With This"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Major Sort"
+msgstr "Major sortieren"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Manual"
+msgstr "Manual"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Merge Cells"
+msgstr "Zellen verbinden"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Middle"
+msgstr "Mittlerer"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Minor Sort"
+msgstr "Minor sortieren"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Insert"
+msgstr "Move einfügen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Paste"
+msgstr "Move Paste"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Multi-line Input Box"
+msgstr "Multi-Line-Eingang Box"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Name"
+msgstr "Name"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Names"
+msgstr "Namen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "No padding"
+msgstr "Nr. padding"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Normal"
+msgstr "Normal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number"
+msgstr "Anzahl"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number Horizontal"
+msgstr "Anzahl Horizontal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "OK"
+msgstr "OK"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Padding"
+msgstr "Padding"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Page Name"
+msgstr "Page Name"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste"
+msgstr "Paste"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste Formats"
+msgstr "Formate einfügen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain Text"
+msgstr "Plain Text"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalc"
+msgstr "Neuberechnen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalculation"
+msgstr "Neuberechnung"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " Redo"
+msgstr "Wieder"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right"
+msgstr "Richtig"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right Border"
+msgstr "Border Right"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SHEET SETTINGS"
+msgstr "BLATT-EINSTELLUNGEN"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save"
+msgstr "Sichern"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save to"
+msgstr "Speichern"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cell Contents"
+msgstr "Set Zellinhalte"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Sort"
+msgstr "Set Zellen zu sortieren"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Value To"
+msgstr "Wert für value"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set to Link format"
+msgstr "Set to Link-Format"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set/Clear Move From"
+msgstr "Setzen / Löschen Verschieben Von"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Cell Settings"
+msgstr "Handy-Einstellungen anzeigen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Sheet Settings"
+msgstr "Show Sheet Einstellungen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show in new browser window"
+msgstr "Karte in neuem Browserfenster"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Size"
+msgstr "Größe"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SocialCalc-save format"
+msgstr "SocialCalc-Speicherformat"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort"
+msgstr "Sortieren"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort Cells"
+msgstr "Sortieren Cells"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Swap Colors"
+msgstr "Farben tauschen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Tab-delimited format"
+msgstr "Tabulatorzeichen getrennten Format"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text"
+msgstr "Text"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text Horizontal"
+msgstr "Text Horizontal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "This is a<br>sample"
+msgstr "Dies ist ein Beispiel <br>"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top"
+msgstr "Spitze"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top Border"
+msgstr "Top Border"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "UNDONE STEPS"
+msgstr "UNDONE STEPS"
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "URL"
+msgstr "URL"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Undo"
+msgstr "Rückgängig"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unmerge Cells"
+msgstr "Unmerge Cells"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Up"
+msgstr "Nach oben"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Value"
+msgstr "Preis"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical"
+msgstr "Vertikale"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Workspace"
+msgstr "Workspace"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[New]"
+msgstr "[NEU]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[None]"
+msgstr "[None]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[select range]"
+msgstr "[select range]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
+#msgstr [ "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
+#msgstr [ "Sun", "Mon", "Tue", "Wed", "Do", "FR", "SA"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["January", "February", "March", "April", "May", "June", "July", "August", "September","October", "November", "December"]
+#msgstr [ "Januar", "Februar", "März", "April", "Mai", "June", "Juli", "August", "September", "Oktober", "November", "Dezember"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+#msgstr[ "Jan", "Feb", "Mar", "Apr", "Mai", "Jun", "Juli", "Aug", "September", "Okt", "November", "Dez"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "AM"
+#msgstr "AM"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "A"
+#msgstr "A"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "PM"
+#msgstr "PM"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "P"
+#msgstr "P"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed number exponent"
+msgstr "Unförmig Zahl Exponent"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unexpected character in formula"
+msgstr "Unerwartete Zeichen in der Formel"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed string"
+msgstr "Unförmig string"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed special value"
+msgstr "Unförmig besonderen Wert"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula (two operators inappropriately in a row)"
+msgstr "Fehler in der Formel (zwei Betreibern unangemessen in einer Reihe)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing open parenthesis in list with comma(s)."
+msgstr "Öffnende Klammer fehlt in der Liste mit Komma (s). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Closing parenthesis without open parenthesis. "
+msgstr "Schließende Klammer ohne öffnende Klammer."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing close parenthesis."
+msgstr "Fehlende schließende Klammer."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing operand."
+msgstr "Fehlende Operanden. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula."
+msgstr "Fehler in der Formel."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error value in formula"
+msgstr "Fehler-Wert in der Formel"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula resulting in bad value"
+msgstr "Fehler in der Formel, was zu unbefriedigenden Wert"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in range value:"
+msgstr "Formel-Ergebnisse im Bereich Wert:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in an bad numeric value"
+msgstr "Formel führt zu einer schlechten numerischen Wert"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Numeric overflow"
+msgstr "Numerischen Ãœberlauf"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet unavailable:"
+msgstr "Noten nicht verfügbar:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cell reference missing when expected."
+msgstr "Zellbezug fehlen, wenn zu erwarten."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet name missing when expected."
+msgstr "Sheet Namen fehlen, wenn zu erwarten."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Circular name reference to name"
+msgstr "Rundschreiben Name Verweis Namen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown name"
+msgstr "Unbekannter Name"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Incorrect arguments to function"
+msgstr "Falsche Argumente Funktion"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function"
+msgstr "Unbekannte Funktion"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LN argument must be greater than 0"
+msgstr "LN Argument muss größer als 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG10 argument must be greater than 0"
+msgstr "LOG10 Argument muss größer als 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG second argument must be numeric greater than 0"
+msgstr "LOG zweite Argument muss größer als 0 numerischen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG first argument must be greater than 0"
+msgstr "LOG erste Argument muss größer als 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "ROUND second argument must be numeric"
+msgstr "ROUND zweite Argument muss numerisch sein"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "DDB life must be greater than 1"
+msgstr "DDB Leben muss größer sein als 1"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SLN life must be greater than 1"
+msgstr "SLN Leben muss größer sein als 1"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Absolute value function. "
+msgstr "Betragsfunktion."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arccosine function. "
+msgstr "Arkuskosinus Trigonometrische Funktion."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if all arguments are true. "
+msgstr "True, wenn alle Argumente wahr sind. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arcsine function. "
+msgstr "Arkussinus Trigonometrische Funktion."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arctan function. "
+msgstr "Trigonometrische arctan-Funktion. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arc tangent function (result is in radians). "
+msgstr "Trigonometrische Arcustangens Funktion (Ergebnis im Bogenmaß)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values. "
+msgstr "Durchschnitt der Werte."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value specified by the index. The values may be ranges of cells. "
+msgstr "Gibt den angegebenen Wert durch den Index. Die Werte können Zellbereiche."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of columns in the range. "
+msgstr "Liefert die Anzahl der Spalten im Bereich. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric cosine function (value is in radians). "
+msgstr "Trigonometrische Cosinus-Funktion (Wert wird in Bogenmaß)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error. "
+msgstr "Zählt die Anzahl von numerischen Werten, nicht leer, Text oder Fehler."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values. "
+msgstr "Zählt die Anzahl der nicht-leere Werte."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of blank values. (Note: '' is not blank.) "
+msgstr "Zählt die Anzahl der Blindwerte. (Anmerkung:''ist nicht leer.)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of number of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). "
+msgstr "Zählt die Anzahl der Zellen in dem Bereich, dass die Kriterien erfüllen. Die Kriterien kann ein Wert ( 'x', 15, 1 3) oder einen Test (> 25)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the appropriate date value given numbers for year, month, and day. For example: DATE(2006,2,1) for February 1, 2006. Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "Liefert das entsprechende Datum Wert gegebenen Zahlen für das Jahr, Monat und Tag. Zum Beispiel: DATE (2006,2,1) für 1. Februar 2006. Hinweis: In diesem Programm ist Tag 1 31. Dezember 1899 und dem Jahr 1900 ist kein Schaltjahr. Einige Programme verwenden 1. Januar 1900, als Tag 1 und Behandlung von 1900 als Schaltjahr. In beiden Fällen sind jedoch Daten am oder nach dem 1. März 1900, das gleiche."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values in the specified field in records that meet the criteria. "
+msgstr "Durchschnitt der Werte in das angegebene Feld in Datensätze, die die Kriterien erfüllen."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of month for a date value. "
+msgstr "Gibt den Tag des Monats für einen Datumswert."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error, in the specified field in records that meet the criteria. "
+msgstr "Zählt die Anzahl von numerischen Werten, nicht leer, Text oder Fehler in der angegebenen Feld Datensätze, die die Kriterien erfüllen."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values in the specified field in records that meet the criteria. "
+msgstr "Zählt die Anzahl der nicht-leere Werte in den angegebenen Bereich in den Aufzeichnungen, die die Kriterien erfüllen."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at the given period of time (the default factor is 2 for double-declining balance). "
+msgstr "Gibt die Höhe der Abschreibungen bei der gegebenen Zeit (die Standard-Faktor 2 für Doppel-degressiven Abschreibung)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in radians into degrees. "
+msgstr "Konvertiert Wert im Bogenmaß in Grad."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value of the specified field in the single record that meets the criteria. "
+msgstr "Gibt den Wert des Feldes in den einzelnen Datensatz, der die Kriterien erfüllt. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Gibt das Maximum der numerischen Werte in den angegebenen Bereich in den Aufzeichnungen, die die Kriterien erfüllen."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values in the specified field in records that meet the criteria. "
+msgstr "Gibt das Ergebnis der Multiplikation der numerischen Werte in den angegebenen Bereich in den Aufzeichnungen, die die Kriterien erfüllen. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Gibt die Stichproben-Standardabweichung der numerischen Werte in den angegebenen Bereich in den Aufzeichnungen, die die Kriterien erfüllen."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Gibt die Standardabweichung der numerischen Werte in den angegebenen Bereich in den Aufzeichnungen, die die Kriterien erfüllen. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Gibt die Summe der numerischen Werte in den angegebenen Bereich in den Aufzeichnungen, die die Kriterien erfüllen."
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Gibt die Varianz der numerischen Werte in den angegebenen Bereich in den Aufzeichnungen, die die Kriterien erfüllen. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Gibt die Varianz der numerischen Werte in den angegebenen Bereich in den Aufzeichnungen, die die Kriterien erfüllen. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest even integer. "
+msgstr "Rundet den Wert in Größe auf die nächste gerade Ganzzahl. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the values are exactly the same, including case, type, etc. "
+msgstr "Gibt true zurück, wenn die Werte sind genau die gleichen, mit Etui, Typ usw. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns e raised to the value power. "
+msgstr "Gibt e hoch der Wert Macht."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns factorial of the value. "
+msgstr "Gibt Fakultät der Wert."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value false. "
+msgstr "Liefert den logischen Wert false. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the starting position within string2 of the first occurrence of string1 at or after start. If start is omitted, 1 is assumed. "
+msgstr "Liefert die Startposition in string2 des ersten Auftretens von string1 bei oder nach dem Start. Wenn start weggelassen wird, wird 1 verwendet. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the future value of repeated payments of money invested at the given rate for the specified number of periods, with optional present value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Liefert den künftigen Wert der wiederholten Zahlung von Geldbeträgen an der angegebenen Preis für die angegebene Anzahl von Perioden investiert, optional mit Barwert (Standard: 0) und Art der Bezahlung (default 0 = am Ende der Periode, 1 = Beginn der Periode). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the row offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. "
+msgstr "Suchen Sie nach dem passenden Wert für den angegebenen Wert in dem Bereich und gibt die entsprechenden Wert in der Zelle durch die Offset-Zeile angegeben. Wenn rangelookup ist 1 (der Standard) und nicht 0 ist, entspricht, wenn innerhalb von numerischen Klammern (match <= value) anstelle der genauen Übereinstimmung."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the hour portion of a time or date/time value. "
+msgstr "Gibt die Stunde Teil einer Zeit oder Datum / Uhrzeit-Wert."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Results in true-value if logical-expression is TRUE or non-zero, otherwise results in false-value. "
+msgstr "Ergebnisse in True-Wert, wenn logisch-Ausdruck wahr oder nicht Null, da sonst falsche Ergebnisse in-Wert."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns a cell or range reference for the specified row and column in the range. If range is 1-dimensional, then only one of rownum or colnum are needed. If range is 2-dimensional and rownum or colnum are zero, a reference to the range of just the specified column or row is returned. You can use the returned reference value in a range, e.g., sum(A1:INDEX(A2:A10,4)). "
+msgstr "Gibt eine Zelle oder einen Bereich Referenz für die angegebene Zeile und Spalte des Bereichs. Wenn Bereich ist 1-dimensional, dann nur eine von rownum oder colnum erforderlich sind. Wenn reicht von 2-dimensionalen und rownum oder colnum Null sind, einen Verweis auf die Reichweite von der angegebenen Spalte oder Zeile zurückgegeben. Sie können den Referenzwert wieder in einem Bereich zu verwenden, z. B. Summe (A1: INDEX (A2: A10, 4)). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value rounded down to the nearest integer (towards -infinity). "
+msgstr "Gibt den Wert abgerundet auf die nächste ganze Zahl (Richtung bis unendlich). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the interest rate at which the cash flows in the range have a net present value of zero. Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "Liefert den Zinssatz, zu dem die Cashflows in dem Bereich einen Barwert von Null. Verwendet ein schrittweiser Prozess, # NUM will return! Fehler, wenn sie nicht konvergiert. Es kann mehr als eine mögliche Lösung. Die Bereitstellung der optionalen erraten Wert kann in bestimmten Situationen helfen, wo es nicht konvergiert oder findet zu einer sachgerechten Lösung (der Standard Vermutung ist, 10%). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is a reference to a blank cell. "
+msgstr "Gibt true zurück, wenn der Wert ist ein Hinweis auf eine leere Zelle. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error but not NA. "
+msgstr "Gibt true zurück, wenn der Wert des Typs Fehler aber nicht NA. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error. "
+msgstr "Gibt true zurück, wenn der Wert des Typs Fehler."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Logical (true/false). "
+msgstr "Gibt true zurück, wenn der Wert vom Typ Logische (true / false). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is the error type NA. "
+msgstr "Gibt true zurück, wenn der Wert der Fehlertyp NA. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is not of type Text. "
+msgstr "Gibt true zurück, wenn der Wert nicht vom Typ Text. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Number (including logical values). "
+msgstr "Gibt true zurück, wenn der Wert vom Typ-Nummer (einschließlich logische Werte). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Text. "
+msgstr "Gibt true zurück, wenn der Wert vom Typ Text. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value. If count is omitted, 1 is assumed. "
+msgstr "Gibt die angegebene Anzahl an Zeichen aus der Text-Wert. Wenn count weggelassen wird, wird 1 verwendet. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of characters in the text value. "
+msgstr "Liefert die Anzahl der Zeichen im Text Wert."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the natural logarithm of the value. "
+msgstr "Liefert den natürlichen Logarithmus des Wertes."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logarithm of the value using the specified base. "
+msgstr "Gibt den Logarithmus der Wert mit dem angegebenen Basis. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the base 10 logarithm of the value. "
+msgstr "Gibt den Logarithmus zur Basis 10 des Wertes. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all uppercase characters converted to lowercase. "
+msgstr "Liefert den Wert in der alle Großbuchstaben in Kleinbuchstaben umgewandelt."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return position (the first is 1) in that range. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. If rangelookup is -1, act like 1 but the bracket is match>=value. "
+msgstr "Suchen Sie nach dem passenden Wert für den angegebenen Wert im Bereich von Position und zurück (der erste ist 1) in diesem Bereich. Wenn rangelookup ist 1 (der Standard) und nicht 0 ist, entspricht, wenn innerhalb von numerischen Klammern (match <= value) anstelle der genauen Übereinstimmung. Wenn rangelookup -1 ist, verhalten sich wie 1, aber die Halterung ist match> = Wert. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values. "
+msgstr "Gibt das Maximum der numerischen Werte. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the specified position. "
+msgstr "Gibt die angegebene Anzahl an Zeichen aus der Text-Wert ab einer bestimmten Position."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minimum of the numeric values. "
+msgstr "Gibt das Minimum der numerischen Werte. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minute portion of a time or date/time value. "
+msgstr "Gibt die Minute ein Teil der Zeit oder Datum / Uhrzeit-Wert."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the remainder of the first value divided by the second. "
+msgstr "Gibt den Rest von den ersten Wert der zweiten unterteilt."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the month part of a date value. "
+msgstr "Gibt den Monat Teil eines Datums-Wert. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value if it is a numeric value otherwise an error. "
+msgstr "Gibt den Wert, wenn es einen numerischen Wert, sonst wird eine Fehlermeldung. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the #N/A error value which propagates through most operations. "
+msgstr "Gibt den # N / A Fehler Wert, der durch die meisten Operationen propagiert."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns FALSE if value is true, and TRUE if it is false. "
+msgstr "Gibt FALSE zurück, wenn der Wert wahr ist und wahr, wenn sie falsch ist. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date/time. "
+msgstr "Gibt das aktuelle Datum / Uhrzeit."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of periods at which payments invested each period at the given rate with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period) has the given present value. "
+msgstr "Gibt die Anzahl von Zeiträumen, in denen Zahlungen investiert jeder Zeit an der angegebenen Rate mit optionalem zukünftigen Wert (Standard: 0) und Art der Bezahlung (default 0 = am Ende der Periode, 1 = Beginn der Periode) hat den gegebenen Barwert. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the net present value of cash flows (which may be individual values and/or ranges) at the given rate. The flows are positive if income, negative if paid out, and are assumed at the end of each period. "
+msgstr "Liefert den Barwert der Cashflows (die einzelnen Werte und / oder Bereiche werden kann) an der angegebenen Rate. Die Ströme sind positiv, wenn das Einkommen negativ gezahlt, wenn aus, und sind am Ende des jeweiligen Zeitraums angenommen. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest odd integer. "
+msgstr "Rundet den Wert in Größe auf die nächste ungerade ganze Zahl ist. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if any argument is true "
+msgstr "True, wenn ein Argument ist richtig "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "The value 3.1415926... "
+msgstr "Der Wert 3.1415926 ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of each payment that must be invested at the given rate for the specified number of periods to have the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Gibt den Betrag jeder Zahlung, die an der angegebenen Preis für die angegebene Anzahl von Perioden investiert werden, um die angegebenen Barwert haben muss, auf Wunsch mit zukünftigen Wert (Standard: 0) und Art der Bezahlung (default 0 = am Ende der Periode, 1 = Beginn des Zeitraums)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the first value raised to the second value power. "
+msgstr "Gibt den ersten Wert angehoben, um den zweiten Wert Macht. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values. "
+msgstr "Gibt das Ergebnis der Multiplikation der numerischen Werte. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with the first letter of each word converted to uppercase and the others to lowercase. "
+msgstr "Liefert den Wert mit dem ersten Buchstaben eines jeden Wortes in Großbuchstaben umgewandelt wurden und die anderen in Kleinbuchstaben. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the present value of the given number of payments each invested at the given rate, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Liefert den Barwert der gegebenen Anzahl der Zahlungen jeweils auf die gegebenen Zinssatz investiert, optional mit zukünftigen Wert (Standard: 0) und Art der Bezahlung (default 0 = am Ende der Periode, 1 = Beginn der Periode)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in degrees into radians. "
+msgstr "Konvertiert in Grad in Bogenmaß. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the rate at which the given number of payments each invested at the given rate has the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "Gibt die Geschwindigkeit, mit der die angegebene Anzahl von Zahlungen an die jeweils gegebenen Zinssatz investiert hat die angegebene Barwert, optional mit zukünftigen Wert (Standard: 0) und Art der Bezahlung (default 0 = am Ende der Periode, 1 = Beginn der Periode). Verwendet ein schrittweiser Prozess, # NUM will return! Fehler, wenn sie nicht konvergiert. Es kann mehr als eine mögliche Lösung. Die Bereitstellung der optionalen erraten Wert kann in bestimmten Situationen helfen, wo es nicht konvergiert oder findet zu einer sachgerechten Lösung (der Standard Vermutung ist, 10%)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the specified number of characters starting from the specified position replaced by text2. "
+msgstr "Gibt text1 mit der angegebenen Anzahl von Zeichen ab der angegebenen Position durch text2 ersetzt. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text repeated the specified number of times. "
+msgstr "Gibt den Text wiederholt die angegebene Anzahl von Zeiten."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the end. If count is omitted, 1 is assumed. "
+msgstr "Gibt die angegebene Anzahl an Zeichen aus der Text-Wert ab dem Ende. Wenn count weggelassen wird, wird 1 verwendet."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value to the specified number of decimal places. If precision is negative, then round to powers of 10. The default precision is 0 (round to integer)."
+msgstr "Runden Sie den Wert auf die angegebene Anzahl von Dezimalstellen. Werden Präzisions-negativ ist, dann rund um die Befugnisse von 10. Die Voreinstellung ist 0 (rund um integer)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of rows in the range. "
+msgstr "Liefert die Anzahl der Zeilen in der Palette."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the second portion of a time or date/time value (truncated to an integer). "
+msgstr "Gibt den zweiten Teil einer Zeit oder Datum / Uhrzeit-Wert (gekürzt auf Integer)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric sine function (value is in radians) "
+msgstr "Trigonometrische Sinusfunktion (Wert wird in Bogenmaß) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at each period of time using the straight-line method. "
+msgstr "Gibt die Höhe der Abschreibungen auf jeder Zeit mit Hilfe der linearen Methode. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Square root of the value "
+msgstr "Quadratwurzel des Wertes"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values. "
+msgstr "Gibt die Stichproben-Standardabweichung der numerischen Werte. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values. "
+msgstr "Gibt die Standardabweichung der numerischen Werte."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the all occurrences of oldtext replaced by newtext. If occurrence is present, then only that occurrence is replaced. "
+msgstr "Gibt text1 mit dem alle Vorkommen von oldtext neuertext ersetzt. Wenn Vorkommen vorhanden ist, dann nur, dass Vorkommen ersetzt wird. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Adds the numeric values. The values to the sum function may be ranges in the form similar to A1:B5. "
+msgstr "Fügt die numerischen Werte. Die Werte, auf die Summe Funktion können Bereiche in der Form ähnlich wie A1: B5. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sums the numeric values of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). If range2 is present, then range1 is tested and the corresponding range2 value is summed. "
+msgstr "Beträge, die numerischen Werte der Zellen in dem Bereich, dass die Kriterien erfüllen. Die Kriterien kann ein Wert ( 'x', 15, 1 3) oder einen Test (> 25). Wenn range2 vorhanden ist, wird dann range1 geprüft und die entsprechenden range2 Wert aufsummiert. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Depreciation by Sum of Year's Digits method. "
+msgstr "Abschreibungen von Sum of Digits Year's Methode. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value or else a null string. "
+msgstr "Liefert den Wert oder auch eine Null-String. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric tangent function (value is in radians) "
+msgstr "Tangente Trigonometrische Funktion (Wert wird in Bogenmaß)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the time value given the specified hour, minute, and second. "
+msgstr "Gibt den Zeit-Wert mit der angegebenen Stunde, Minute und Sekunde."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date (an integer). Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "Gibt das aktuelle Datum (eine Ganzzahl). Hinweis: In diesem Programm ist Tag 1 31. Dezember 1899 und dem Jahr 1900 ist kein Schaltjahr. Einige Programme verwenden 1. Januar 1900, als Tag 1 und Behandlung von 1900 als Schaltjahr. In beiden Fällen sind jedoch Daten am oder nach dem 1. März 1900, das gleiche. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with leading, trailing, and repeated spaces removed. "
+msgstr "Liefert den Wert mit führenden, abschließenden und wiederholten Leerzeichen entfernt. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value true. "
+msgstr "Liefert den logischen Wert true."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Truncates the value to the specified number of decimal places. If precision is negative, truncate to powers of 10. "
+msgstr "Schneidet den Wert auf die angegebene Anzahl von Dezimalstellen. Ist die Präzision negativ abschneiden, die Befugnisse von 10. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all lowercase characters converted to uppercase. "
+msgstr "Liefert den Wert in der alle Kleinbuchstaben in Großbuchstaben umgewandelt. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts the specified text value into a numeric value. Various forms that look like numbers (including digits followed by %, forms that look like dates, etc.) are handled. This may not handle all of the forms accepted by other spreadsheets and may be locale dependent. "
+msgstr "Konvertiert den angegebenen Text-Wert in einem numerischen Wert. Verschiedene Formen, die aussehen wie Zahlen (einschließlich Ziffern, gefolgt von%, Formen, die aussehen, Termine usw.) verarbeitet werden. Dies führt unter Umständen nicht alle Formen von anderen Tabellenkalkulationen akzeptiert und kann locale abhängig. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values. "
+msgstr "Gibt die Varianz der numerischen Werte. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values. "
+msgstr "Gibt die Varianz der numerischen Werte."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the column offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match>=value) instead of exact match. "
+msgstr "Suchen Sie nach dem passenden Wert für den angegebenen Wert in dem Bereich und gibt die entsprechenden Wert in der Zelle durch die Offset-Spalte angegeben. Wenn rangelookup ist 1 (der Standard) und nicht 0 ist, entspricht, wenn innerhalb von numerischen Klammern (match> = Wert) anstelle der genauen Übereinstimmung. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of week specified by the date value. If type is 1 (the default), Sunday is day and Saturday is day 7. If type is 2, Monday is day 1 and Sunday is day 7. If type is 3, Monday is day 0 and Sunday is day 6. "
+msgstr "Gibt den Tag der Woche nach dem Datum Wert angegeben. Bei Typ 1 (der Standard), Sonntag ist Tag und Samstag ist 7 Tage. Bei Typ 2 ist, Tag 1 Montag und Sonntag ist 7 Tage. Wird der Typ 3 ist, ist Montag Tag 0 und Sonntag ist Tag 6."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the year part of a date value. "
+msgstr "Gibt das Jahr Teil eines Datums-Wert."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value"
+msgstr "Wert"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value1, value2, ..."
+msgstr "Wert1, Wert2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "valueX, valueY"
+msgstr "valueX, valueY"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "index, value1, value2, ..."
+msgstr "Index, Wert1, Wert2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range"
+msgstr "Bereich"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, criteria"
+msgstr "Bereich, Suchkriterien"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "year, month, day"
+msgstr "Jahr, Monat, Tag"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "databaserange, fieldname, criteriarange"
+msgstr "databaserange, fieldname, criteriarange"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period [, factor]"
+msgstr "Anschaffungswert, Restwert, Lebensdauer, Zeitraum [Faktor]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "string1, string2 [, start]"
+msgstr "string1, string2 [, start]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [pv, [paytype]]"
+msgstr "rate, n, Zahlung, [PV, [paytype]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, row, [rangelookup]"
+msgstr "Wert, Reichweite, Reihe, [rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "logical-expression, true-value, false-value"
+msgstr "logisch-Ausdruck, true-Wert, false-Wert"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, rownum, colnum"
+msgstr "Bereich, rownum, colnum"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, [guess]"
+msgstr "Bereich, [guess]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, count"
+msgstr "text, count"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, base"
+msgstr "Wert, Basis"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, [rangelookup]"
+msgstr "Wert, Bereich, [rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, start, length"
+msgstr "Text, start, length"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, payment, pv, [fv, [paytype]]"
+msgstr "Rate, Zahlung, pv [fv [paytype]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, value1, value2, ..."
+msgstr "Zins, Wert1, Wert2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, pv, [fv, [paytype]]"
+msgstr "rate, n, pv [fv [paytype]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [fv, [paytype]]"
+msgstr "rate, n, Zahlung, [fv [paytype]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "n, payment, pv, [fv, [paytype, [guess]]]"
+msgstr "n, Zahlung, pv [fv [paytype, [guess]]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, start, length, text2"
+msgstr "text1, start, length, text2"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, [precision]"
+msgstr "Wert, [Genauigkeit]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime"
+msgstr "Anschaffungswert, Restwert, Lebensdauer"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period"
+msgstr "Anschaffungswert, Restwert, Leben, Zeit"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, oldtext, newtext [, occurrence]"
+msgstr "text1, oldtext, neuertext [, occurrence]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range1, criteria [, range2]"
+msgstr "range1, Kriterien [, range2]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "hour, minute, second"
+msgstr "Stunde, Minute, Sekunde"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, col, [rangelookup]"
+msgstr "Wert, Bereich, col, [rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date, [type]"
+msgstr "Datum, [type]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date"
+msgstr "Datum"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["all", "stat", "lookup", "datetime", "financial", "test", "math", Text]
+#msgstr [ "all", "stat", "Lookup", "datetime", "Finanzdienstleistungen", "test", "Mathematik", Text]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "All"
+msgstr "Alle"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Statistics"
+msgstr "Statistik"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Lookup"
+msgstr "Lookup"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Date & Time"
+msgstr "Datum & Zeit"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Financial"
+msgstr "Financial"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Test"
+msgstr "Test"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Math"
+msgstr "Math"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cells to Graph"
+msgstr "Zellen, die Grafik"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Graph"
+msgstr "Set Zellen, Diagramm"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph Type"
+msgstr "Diagramm TypeGraph Typ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "filter:alpha(opacity=90);opacity:.9;"
+msgstr "filter: alpha (opacity = 90); opacity: .9"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain"
+msgstr "Plain"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph"
+msgstr "Graph"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Pie Chart"
+msgstr "Kreisdiagramm"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "help"
+msgstr "Hilfe"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal Bar"
+msgstr "Reck"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical Bar"
+msgstr "Vertical Bar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Line Chart"
+msgstr "Liniendiagramm"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plot Points"
+msgstr "Plot Points"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown range name"
+msgstr "Unbekannter Bereichsname"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hide Help"
+msgstr "Hilfe ausblenden"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Max "
+msgstr "Max "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Min "
+msgstr "Min "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " OK "
+msgstr " OK " \ No newline at end of file
diff --git a/po/es.po b/po/es.po
new file mode 100644
index 0000000..9f96eb2
--- /dev/null
+++ b/po/es.po
@@ -0,0 +1,1475 @@
+# Copyright (C) 2010 THE PACKAGE"S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# olpc user <olpc@localhost.localdomain>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: SocialCalcActivity.activity\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-01-07 14:46+0000\n"
+"PO-Revision-Date: 2010-01-09 21:53+0530\n"
+"Last-Translator: Diksha<dksh.khatri@gmail.com>\n"
+"Language-Team: Hindi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: activity/activity.info:2
+msgid "SocialCalcActivity"
+msgstr "SocialCalcActivity"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:10
+#msgid "t"
+#msgstr "t"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:13
+msgid "Browser not supported. "
+msgstr "Navegador no es compatible."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:14
+msgid "Internal SocialCalc error (probably an internal bug):"
+msgstr "Error Interno SocialCalc (probablemente un error interno)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:20
+msgid "Unknown col type item"
+msgstr "Elemento desconocido en el tipo de columna"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:21
+msgid "Unknown row type item"
+msgstr "Elemento desconocido en el tipo de fila"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:22
+msgid "Unknown line type"
+msgstr "Tipo de linea desconocida"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:28
+msgid "Unknown cell type item"
+msgstr "Elemento desconocido en el tipo de celda"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:36
+msgid "Unknown sheet command: "
+msgstr "Comando desconocido de hoja de calculo: "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:37
+msgid "Unknown set coord command: "
+msgstr "Comando de fijar coordenadas desconocido: "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:38
+msgid "Unknown command: "
+msgstr "Comando Desconocido:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:42
+msgid "Circular reference to "
+msgstr "Referencia circular a "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:52
+msgid "padding:2px 2px 1px 2px;vertical-align:top;"
+msgstr "relleno:2px 2px 1px 2px;alineación-vertical:arriba;"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:53
+msgid "normal normal"
+msgstr "normal normal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:54
+msgid "small"
+msgstr "pequeño"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:55
+msgid "Verdana,Arial,Helvetica,sans-serif"
+msgstr "Verdana, Arial, Helvetica, sans-serif"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:92
+msgid "Render Context must have a sheet object"
+msgstr "Render contexto debe tener un objeto de hoja"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Executing..."
+msgstr "En ejecución ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Displaying..."
+msgstr "Viendo ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Ordering..."
+msgstr "Pedidos ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating..."
+msgstr "Calculando .."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating... Loading Sheet..."
+msgstr "Calculando ... Cargando ... Hoja de"
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "doing server function "
+msgstr "haciendo la función de servidor "
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " in cell "
+msgstr "en la celda "
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculation start..."
+msgstr "Iniciar el cálculo de ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SUM"
+msgstr "SUM"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Multi-line text: Click icon on right to edit]"
+msgstr "[Texto multilínea: Haga clic en el icono sobre el derecho a editar]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function "
+msgstr "Función desconocida"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane vertically"
+msgstr "Arrastre para bloquear el panel vertical"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane horizontally"
+msgstr "Arrastre para bloquear el panel horizontal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Center"
+msgstr "Centrar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Left"
+msgstr "Alinear a la izquierda "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Right"
+msgstr "Alinear a la derecha"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Alignment"
+msgstr "Alineación"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit"
+msgstr "Auditoría"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit Trail This Session"
+msgstr "Audit Trail esta sesión"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto"
+msgstr "Auto"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto Sum"
+msgstr "Auto Sum"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto w/ commas"
+msgstr "W Auto / comas"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Automatic"
+msgstr "Automático"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Background"
+msgstr "Antecedentes"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold"
+msgstr "Negrita"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold &amp; Italics"
+msgstr "Negrita y cursiva"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold Italic"
+msgstr "Bold Italic"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders"
+msgstr "Fronteras"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders Off"
+msgstr "Fronteras Off"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders On"
+msgstr "En las fronteras"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom"
+msgstr "Inferior"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom Border"
+msgstr "Abajo las fronteras"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CELL SETTINGS"
+msgstr "CELL AJUSTES"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CSV format"
+msgstr "CSV format"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cancel"
+msgstr "Cancel"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Category"
+msgstr "Category"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Center"
+msgstr "Centro"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear"
+msgstr "Clear"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear SocialCalc Clipboard"
+msgstr "Clear SocialCalc Portapapeles"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clipboard"
+msgstr "Portapapeles"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Color"
+msgstr "Color"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Column"
+msgstr "Columna"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Comment"
+msgstr "Comment"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Copy"
+msgstr "Copiar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Custom"
+msgstr "Costumbre"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cut"
+msgstr "Cortar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default"
+msgstr "Default"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Alignment"
+msgstr "Default Alineación"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Column Width"
+msgstr "Default Ancho de columna"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Font"
+msgstr "Fuente por Defecto"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Format"
+msgstr "el formato predeterminado"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Padding"
+msgstr "por defecto de relleno"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete"
+msgstr "Borrar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Column"
+msgstr "Eliminar columna"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Contents"
+msgstr "Eliminar contenido"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Row"
+msgstr "Eliminar Fila"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Description"
+msgstr "Descripción"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Display Clipboard in"
+msgstr "Mostrar Portapapeles"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Down"
+msgstr "Down"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Edit"
+msgstr "Editar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Existing Names"
+msgstr "Los nombres existentes"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Family"
+msgstr "Familia"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Down"
+msgstr "Rellenar hacia abajo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Right"
+msgstr "Rellenar hacia la derecha"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Font"
+msgstr "Fuente"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Format"
+msgstr "Formato"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula"
+msgstr "La Fórmula"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Function List"
+msgstr "Lista de funciones"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Functions"
+msgstr "Funciones"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Grid"
+msgstr "Grid"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hidden"
+msgstr "Oculto"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal"
+msgstr "Horizontal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Column"
+msgstr "Insertar Columna"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Row"
+msgstr "Insertar Fila"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Italic"
+msgstr "Cursiva"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Last Sort"
+msgstr "Ordenar pasado"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left"
+msgstr "Izquierda"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left Border"
+msgstr "Izquierda Borde"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link"
+msgstr "Vínculo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link Input Box"
+msgstr "Vínculo de entrada de caja"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "List"
+msgstr "Lista"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Load SocialCalc Clipboard With This"
+msgstr "Cargar SocialCalc portapapeles con este"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Major Sort"
+msgstr "Manual"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Manual"
+msgstr "Manual"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Merge Cells"
+msgstr "Combinar Celdas"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Middle"
+msgstr "Medio"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Minor Sort"
+msgstr "Ordenar Menor"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Insert"
+msgstr "Mover Insertar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Paste"
+msgstr "Mover Pegar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Multi-line Input Box"
+msgstr "Multi-línea de entrada de caja"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Name"
+msgstr "Nombre"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Names"
+msgstr "Nombres"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "No padding"
+msgstr "No hay relleno"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Normal"
+msgstr "Normal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number"
+msgstr "Número"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number Horizontal"
+msgstr "Número Horizontal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "OK"
+msgstr "OK"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Padding"
+msgstr "relleno"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Page Name"
+msgstr "Nombre de página"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste"
+msgstr "Pegar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste Formats"
+msgstr "Pegar formatos"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain Text"
+msgstr "Texto plano"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalc"
+msgstr "Recalc"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalculation"
+msgstr "Nuevo cálculo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " Redo"
+msgstr "Rehacer"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right"
+msgstr "Derecha"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right Border"
+msgstr "Derecho de fronteras"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SHEET SETTINGS"
+msgstr "HOJA DE AJUSTES"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save"
+msgstr "Guardar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save to"
+msgstr "Guardar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cell Contents"
+msgstr "Establecer la célula Contenidos"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Sort"
+msgstr "Establecer celdas que desee ordenar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Value To"
+msgstr "Establecer el valor a"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set to Link format"
+msgstr "Se establece en formato de vínculo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set/Clear Move From"
+msgstr "Establecer / Borrar pasar de"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Cell Settings"
+msgstr "Mostrar configuración de la célula"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Sheet Settings"
+msgstr "Mostrar Hoja de Configuración"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show in new browser window"
+msgstr "Mostrar en ventana nueva del navegador"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Size"
+msgstr "Tamaño"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SocialCalc-save format"
+msgstr "formato para guardar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort"
+msgstr "Ordenar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort Cells"
+msgstr "Las células Ordenar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Swap Colors"
+msgstr "Intercambio de colores"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Tab-delimited format"
+msgstr "formato delimitado por tabuladores"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text"
+msgstr "Texto"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text Horizontal"
+msgstr "Texto Horizontal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "This is a<br>sample"
+msgstr "Esta es una muestra de <br>"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top"
+msgstr "Tope"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top Border"
+msgstr "Arriba las fronteras"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "UNDONE STEPS"
+msgstr "Undone pasos"
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "URL"
+msgstr "URL"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Undo"
+msgstr "Deshacer"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unmerge Cells"
+msgstr "unmerge Celdas"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Up"
+msgstr "Up"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Value"
+msgstr "Valor"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical"
+msgstr "Vertical"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Workspace"
+msgstr "Area de trabajo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[New]"
+msgstr "[Nuevo]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[None]"
+msgstr "[No]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[select range]"
+msgstr "[selecta gama]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
+#msgstr ["Domingo", "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
+#msgstr ["Dom", "Lun", "Mar", "Mie", "Jue", "Vie", "Sab"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["January", "February", "March", "April", "May", "June", "July", "August", "September","October", "November", "December"]
+#msgstr ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"],
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+#msgstr ["Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "AM"
+#msgstr "AM"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "A"
+#msgstr "A"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "PM"
+#msgstr "PM"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "P"
+#msgstr "P"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed number exponent"
+msgstr "Número exponente inapropiadamente formado"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unexpected character in formula"
+msgstr "Caracter inesperado en la formula"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed string"
+msgstr "Cadena formada inapropiadamente"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed special value"
+msgstr "Valor especial formado inapropiadamente"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula (two operators inappropriately in a row)"
+msgstr "Error en formula (dos operadores en la fila inapropiadamente)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing open parenthesis in list with comma(s)."
+msgstr "Falta abrir paréntesis en la lista con coma(s). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Closing parenthesis without open parenthesis. "
+msgstr "Cerrar parentesis sin el paréntesis de abrir. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing close parenthesis."
+msgstr "Cerrar paréntesis faltante. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing operand."
+msgstr "Missing operand. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula."
+msgstr "Error en la formula. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error value in formula"
+msgstr "Error de valor en la formula"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula resulting in bad value"
+msgstr "Error en la formula resultando un mal valor"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in range value:"
+msgstr "Resultado de la formula en un valor de rango:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in an bad numeric value"
+msgstr "Resultado de la formula en un valor numérico malo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Numeric overflow"
+msgstr "Desbordamiento numérico"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet unavailable:"
+msgstr "Hoja no disponible:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cell reference missing when expected."
+msgstr "Falta referencia de la celda cuando es esperada."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet name missing when expected."
+msgstr "Falta nombre de la hoja cuando es esperada."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Circular name reference to name"
+msgstr "Referencia circular del nombre para el nombre"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown name"
+msgstr "Nombre desconocido"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Incorrect arguments to function"
+msgstr "Argumentos incorrectos de la función"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function"
+msgstr "Función desconocida"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LN argument must be greater than 0"
+msgstr "El argumento LN tiene que ser mayor que 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG10 argument must be greater than 0"
+msgstr "El argumento LOG10 tiene que ser mayor que 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG second argument must be numeric greater than 0"
+msgstr "El segundo argumento de LOG tiene que ser numérico mayor que 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG first argument must be greater than 0"
+msgstr "El primer argumento de LOG tiene que ser mayor que 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "ROUND second argument must be numeric"
+msgstr "El segundo argumento de REDONDEAR tiene que ser numérico"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "DDB life must be greater than 1"
+msgstr "Vida DDB tiene que ser mayor a 1"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SLN life must be greater than 1"
+msgstr "Vida SLN tiene que ser mayor a 1"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Absolute value function. "
+msgstr "Función valor absoluto. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arccosine function. "
+msgstr "Función trigonometrica arccoseno. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if all arguments are true. "
+msgstr "Verdadero si todos los argumentos son verdaderos. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arcsine function. "
+msgstr "Función trigonometrica arcseno. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arctan function. "
+msgstr "Función trigonometrica arctangente. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arc tangent function (result is in radians). "
+msgstr "Función trigonometrica arc tangente (resultado es en radianes). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values. "
+msgstr "Promedia los valores."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value specified by the index. The values may be ranges of cells. "
+msgstr "Regresa el valor especificado por el indice. Los valores pueden ser rangos de celdas. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of columns in the range. "
+msgstr "Regresa el número de columnas en el rango. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric cosine function (value is in radians). "
+msgstr "Función trigonometrica coseno (valor es en radianes)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error. "
+msgstr "Cuenta el número de valores numéricos, no en blanco, texto, o error. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values. "
+msgstr "Cuenta el número de valores no en blanco. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of blank values. (Note: '' is not blank.) "
+msgstr "Cuenta el número de valores en blanco. (Nota: '' no es en blanco.) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of number of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). "
+msgstr "Cuenta el número de número de celdas en el rango que cumple los criterios. El criterio puede ser un valor ('x', 15, 1+3) o una prueba (>25). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the appropriate date value given numbers for year, month, and day. For example: DATE(2006,2,1) for February 1, 2006. Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "Regresa el valor de datos apropiado dados los números para año, mes, y día. Por ejemplo: FECHA(2006,2,1) para Febrero 1, 2006. Nota: En este programa, el día 1 es Diciembre 31, 1899 y el año 1900 no es un año bisiesto. Algunos programas usan Enero 1, 1900, como día 1 y tratan 1900 como un año bisiesto. En ambos casos, sin embargo, fechas en o despues de Marzo 1, 1900, son lo mismo. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values in the specified field in records that meet the criteria. "
+msgstr "Promedia los valores en el campo especifico en archivos que cumplan con el criterio. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of month for a date value. "
+msgstr "Regresa el día del mes por un valor de fecha. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error, in the specified field in records that meet the criteria. "
+msgstr "Cuenta el número de valores numéricos, no en blanco, texto, o error, en el campo especifico en archivos que cumplan con el criterio. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values in the specified field in records that meet the criteria. "
+msgstr "Cuenta el número de valores no en blanco en el campo especifico en archivos que cumplan con el criterio. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at the given period of time (the default factor is 2 for double-declining balance). "
+msgstr "Regresa la cantidad de depreciación en un periodo de tiempo dado (el factor predeterminado es 2 por doble balance doble decreciente)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in radians into degrees. "
+msgstr "Convierte el valor de radianes en grados. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value of the specified field in the single record that meets the criteria. "
+msgstr "Regresa el valor del campo especificado en un simple registro que cumpla con el criterio. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Regresa el máximo de los valores numéricos en el campo especificado en registros que cumplan con el criterio. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values in the specified field in records that meet the criteria. "
+msgstr "Regresa el resultado de multiplicar los valores numéricos en el campo especificado en registros que cumplan con el criterio. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Regresa la desviación estandard de la muestra de los valores numéricos en el campo especificado en registros que cumplan con el criterio. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Regresa la desviación estandard de los valores numéricos en el campo especificado en registros que cumplan con el criterio. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Regresa la suma de los valores numéricos en el campo especificado en registros que cumplan con el criterio. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Regresa la varianza de la muestra de los valores numéricos en el campo especificado en registros que cumplan con el criterio. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Regresa la varianza de los valores numéricos en el campo especificado en registros que cumplan con el criterio. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest even integer. "
+msgstr "Redondea por encima el valor en magnitud hacia el entero par mas cercano. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the values are exactly the same, including case, type, etc. "
+msgstr "Regresa verdadero si los valores son exactamente los mismos, incluyendo caso, tipo, etc. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns e raised to the value power. "
+msgstr "Regresa e incrementa a la potencia del valor. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns factorial of the value. "
+msgstr "Regresa el factorial del valor. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value false. "
+msgstr "Regresa el valor logico falso. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the starting position within string2 of the first occurrence of string1 at or after start. If start is omitted, 1 is assumed. "
+msgstr "Regresa la posición de empezar dentro de la cuerda2 de la primera occurrencia de la cuerda1 en o despues de iniciar. Si iniciar es omitido, 1 es asumido. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the future value of repeated payments of money invested at the given rate for the specified number of periods, with optional present value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Regresa el valor futuro de pagos repetidos de dinero invertido a una tasa determinada por el número especificado de periodos, con valor presente opcional (predeterminado 0) y tipo de pago (predeterminado 0 = al finall del periodo, 1 = al inicio del periodo). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the row offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. "
+msgstr "Busca por el valor que coincida para un valor determinado en el rango y regresa el valor correspondiente en la celda especificada para la fila de desplazamiento. Si el rango de busqueda es 1 (el predeterminado) y no 0, coincide si dentro de los parentesis numéricos (coincide<=valor) en vez de coincidencia exacta. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the hour portion of a time or date/time value. "
+msgstr "Regresa la porción de hora de un valor de hora o fecha/hora. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Results in true-value if logical-expression is TRUE or non-zero, otherwise results in false-value. "
+msgstr "Regresa el valor-verdadero si la expresión-logica es VERDADERA o no-cero, de otra forma resulta en un valor-falso. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns a cell or range reference for the specified row and column in the range. If range is 1-dimensional, then only one of rownum or colnum are needed. If range is 2-dimensional and rownum or colnum are zero, a reference to the range of just the specified column or row is returned. You can use the returned reference value in a range, e.g., sum(A1:INDEX(A2:A10,4)). "
+msgstr "Regresa una celda o una referencia de rango para la fila y columna especificada en el rango. Si el rango es 1-dimensional, entonces unicamente se necesita una de las filanúmero o columnanúmero. Si el rango es 2-dimensional y la filanúmero o columnanúmero son cero, una referencia del rango de solo la columna o fila especificada es regresada. Usted puede usar el valor de la referencia regresada en un rango, ejemplo, sum(A1:INDEX(A2:A10,4)). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value rounded down to the nearest integer (towards -infinity). "
+msgstr "Regresa el valor redondeado por debajo hacia el entero mas cercano (hacia -infinito). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the interest rate at which the cash flows in the range have a net present value of zero. Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "Regresa la tasa de interes a la cual el flujo de efectivo en el rango tiene un valor presente neto de cero. Usa un proceso interactivo que regresara un error #NUM! si no coincide. Puede haber mas de una solución posible. Proveyendo el valor opcional suponer puede ayudar en ciertas situaciones donde no coincide o encuentra una solución inapropiada (el suponer predeterminado es 10%). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is a reference to a blank cell. "
+msgstr "Regresa verdadero si el valor es una referencia de una celda en blanco. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error but not NA. "
+msgstr "Regresa verdadero si el valor es del tipo Error pero no NA. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error. "
+msgstr "Regresa verdadero si el valor es de tipo Error. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Logical (true/false). "
+msgstr "Regresa verdadero si el valor es de tipo Lógico (verdadero/falso). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is the error type NA. "
+msgstr "Regresa verdadero si el valor es un error de tipo NA. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is not of type Text. "
+msgstr "Regresa verdadero si el valor no es de tipo Texto. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Number (including logical values). "
+msgstr "Regresa verdadero si el valor es de tipo Número (incluyendo valores lógicos). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Text. "
+msgstr "Regresa verdadero si el valor es de tipo Texto. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value. If count is omitted, 1 is assumed. "
+msgstr "Regresa el número especificado de caracteres del valor de texto. Si contar es omitido, 1 es asumido. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of characters in the text value. "
+msgstr "Regresa el número de caracteres en el valor de texto. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the natural logarithm of the value. "
+msgstr "Regresa el logaritmo natural del valor. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logarithm of the value using the specified base. "
+msgstr "Regresa el logritmo del valor usando la base especificada. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the base 10 logarithm of the value. "
+msgstr "Regresa el logritmo en base 10 del valor. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all uppercase characters converted to lowercase. "
+msgstr "Regresa el valor de texto con todos los caracteres en mayuscula convertidos en minuscula. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return position (the first is 1) in that range. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. If rangelookup is -1, act like 1 but the bracket is match>=value. "
+msgstr "Busca el valor que coincida para el valor determinado en el rango y posición de regreso (el primero es 1) en ese rango. Si el rango de busqueda es 1 (el predeterminado) y no 0, coincide si dentro de los parentesis numéricos (coincide<=valor) en vez de un coincidencia exacta. Si el rango de busqueda es -1, actua como 1 pero el parentesis es coincide>=valor. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values. "
+msgstr "Regresa el maximo de los valores numéricos. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the specified position. "
+msgstr "Regresa el número especificado de caracteres desde el valor de texto empezando en la posición especificada. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minimum of the numeric values. "
+msgstr "Regresa el minimo de los valores numéricos. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minute portion of a time or date/time value. "
+msgstr "Regresa la porción del minuto de un valor tiempo o fecha/tiempo. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the remainder of the first value divided by the second. "
+msgstr "Regresa el residuo del primer valor dividido por el segundo. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the month part of a date value. "
+msgstr "Regresa la parte del mes de un valor de fecha. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value if it is a numeric value otherwise an error. "
+msgstr "Regresa el valor si es un valor numérico de lo contrario un error. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the #N/A error value which propagates through most operations. "
+msgstr "Regresa el valor error #N/A el cual se propaga a travez de casi todas las operaciones. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns FALSE if value is true, and TRUE if it is false. "
+msgstr "Regresa FALSO si el valor es verdadero, y VERDADERO si es falso. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date/time. "
+msgstr "Regresa la fecha/tiempo actual. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of periods at which payments invested each period at the given rate with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period) has the given present value. "
+msgstr "Regresa el número de periodos en el cual pagos invertidos cada periodo a una tasa dada con un valor futuro opcional (predeterminado 0) y tipo de pago (predeterminado 0 = al final del periodo, 1 = inicio del periodo) tiene el valor presente dado. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the net present value of cash flows (which may be individual values and/or ranges) at the given rate. The flows are positive if income, negative if paid out, and are assumed at the end of each period. "
+msgstr "Regresa el valor presente neto de flujo de efectivo (el cual pueden ser valores individuales y/o rangos) a una tasa determinada. Los flujos son positivos si ingreso, negativo si es pagado en su totalidad, y son asumidos al final de cada periodo. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest odd integer. "
+msgstr "Redondea por encima el valor en magnitud al impar mas cercano. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if any argument is true "
+msgstr "Verdadero si cualquier argumento es verdadero "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "The value 3.1415926... "
+msgstr "El valor 3.1415926..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of each payment that must be invested at the given rate for the specified number of periods to have the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Regresa la cantidad de cada pago que tiene que estar invertida a una tasa determinada por un especificado número de periodos para tener un valor presente especificado, con un valor futuro opcional (predeterminado 0) y tipo de pago (predeterminado 0 = al final del periodo, 1 = inicio del periodo)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the first value raised to the second value power. "
+msgstr "Regresa el primer valor incrementado al valor de la segunda potencia. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values. "
+msgstr "Regresa el resultado de multiplicar los valores numéricos. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with the first letter of each word converted to uppercase and the others to lowercase. "
+msgstr "Regresa el valor de texto con la primera letra de cada palabra convertida en mayuscula y las otras en minuscula. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the present value of the given number of payments each invested at the given rate, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Regresa el valor presente de un número determinado de pagos cada vez invertido a una tasa dada, con un valor futuro opcional (predeterminado 0) y un tipo de pago (predeterminado 0 = al final del periodo, 1 = inicio del periodo). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in degrees into radians. "
+msgstr "Convierte el valor de grados a radianes. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the rate at which the given number of payments each invested at the given rate has the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "Regresa la tasa a la cual el número dado de pagos cada vez invertido a una tasa dada tiene el valor presente especificado, con valor futuro opcional (predeterminado 0) y tipo de pago (predeterminado 0 = al final del periodo, 1 = inicio del periodo). Usa un proceso interactivo que regresara un error #NUM! si no coincide. Puede haber mas de una posible solución. Proveyendo el valor suponer opcional puede ayudar en ciertas situaciones donde no coincide o encuentra una solución inapropiada (el suponer predeterminado es 10%). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the specified number of characters starting from the specified position replaced by text2. "
+msgstr "Regresa texto1 con el número especificado de caracteres empezando en la posición especificada reemplazada por texto2. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text repeated the specified number of times. "
+msgstr "Regresa el texto repetido el número especificado de veces. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the end. If count is omitted, 1 is assumed. "
+msgstr "Regresa el número especificado de caracteres de el valor de texto empezando por el final. Si contar es omitido, 1 es asumido. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value to the specified number of decimal places. If precision is negative, then round to powers of 10. The default precision is 0 (round to integer). "
+msgstr "Redondea el valor al número especificado de lugares decimales. Si la precisión es negativa, entonces redondea a la potencia de 10. La precisión predeterminada es 0 (redondeada al entero). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of rows in the range. "
+msgstr "Regresa el número de filas en el rango. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the second portion of a time or date/time value (truncated to an integer). "
+msgstr "Regresa la segunda porción de un valor tiempo o fecha/tiempo (truncado un entero). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric sine function (value is in radians) "
+msgstr "Función trigonometrica seno (valor esta en radianes) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at each period of time using the straight-line method. "
+msgstr "Regresa la cantidad de depreciación a cada periodo de tiempo usando el metodo de la linea-recta. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Square root of the value "
+msgstr "Raiz cuadrada del valor "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values. "
+msgstr "Regresa la desviación estandard de la muestra de los valores numéricos. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values. "
+msgstr "Regresa la desviación estandard de los valores numéricos. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the all occurrences of oldtext replaced by newtext. If occurrence is present, then only that occurrence is replaced. "
+msgstr "Regresa texto1 con todas las ocurrencias del textoviejo reemplazado por textonuevo. Si ocurrencia esta presente, entonces unicamente la ocurrencia es reemplazada. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Adds the numeric values. The values to the sum function may be ranges in the form similar to A1:B5. "
+msgstr "Adiciona los valores numéricos. Los valores para la función suma pueden ser rangos en la forma similar a A1:B5. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sums the numeric values of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). If range2 is present, then range1 is tested and the corresponding range2 value is summed. "
+msgstr "Suma los valores numéricos de las celdas en el rango que cumplan con el criterio. El criterio puede ser un valor ('x', 15, 1+3) o una prueba (>25). Si rango2 esta presente, entonces rango1 es probado y el correspondiente valor rango2 es sumado. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Depreciation by Sum of Year's Digits method. "
+msgstr "Depreciación por Suma de metodo de los Digitos de los Años. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value or else a null string. "
+msgstr "Regresa el valor de texto o de otro modo una cadena nula. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric tangent function (value is in radians) "
+msgstr "Función trigonométrica tangente (valor esta en radianes) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the time value given the specified hour, minute, and second. "
+msgstr "Regresa el valor de tiempo dada la hora, minuto, y segundo especificado. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date (an integer). Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "Regresa la fecha actual (un entero). Nota: En este programa, día 1 es Diciembre 31, 1899 y el año 1900 no es un año bisiesto. Algunos programas usan Enero 1, 1900, como día 1 y trata 1900 como un año bisiesto. En ambos casos, sin embargo, fechas en o despues de Marzo 1, 1900, son lo mismo. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with leading, trailing, and repeated spaces removed. "
+msgstr "Regresa el valor texto con iniciales, finales, y espacios removidos repetidos. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value true. "
+msgstr "Regresa el valor logico verdadero. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Truncates the value to the specified number of decimal places. If precision is negative, truncate to powers of 10. "
+msgstr "Trunca el valor especificado de lugares decimales. Si la precisión es negativa, trunca a la potencia de 10. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all lowercase characters converted to uppercase. "
+msgstr "Regresa el valor texto con todos los caracteres en minusculas convertidos a mayusculas. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts the specified text value into a numeric value. Various forms that look like numbers (including digits followed by %, forms that look like dates, etc.) are handled. This may not handle all of the forms accepted by other spreadsheets and may be locale dependent. "
+msgstr "Convierte el valor texto especificado en un valor numérico. Varias formas que parecen como números (incluyendo digitos seguidos por %, formas que parecen como fechas, etc.) son manejados. Este puede que no maneje todas las formas aceptadas por otras hojas electrónicas y puede ser dependiente local. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values. "
+msgstr "Regresa la varianza de la muestra de los valores numéricos. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values. "
+msgstr "Regresa la varianza de los valores numéricos. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the column offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match>=value) instead of exact match. "
+msgstr "Busca por el valor correspodiente para el valor dado en el rango y regresa el valor correspondiente en la celda especificada por la columna desplazada. Si el rango de busqueda es 1 (el predeterminado) y no 0, coincide si dentro de los parentesis numéricos (coincide>=valor) en vez de la exacta coincidencia. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of week specified by the date value. If type is 1 (the default), Sunday is day and Saturday is day 7. If type is 2, Monday is day 1 and Sunday is day 7. If type is 3, Monday is day 0 and Sunday is day 6. "
+msgstr "Regresa el día de la semana especificado por el valor fecha. Si es tipo 1 (el predeterminado), Domingo es día y Sabado es día 7. Si es tipo 2, Lunes es día y Domingo es día 7. Si es tipo 3, Lunes es día 0 y Domingo es día 6. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the year part of a date value. "
+msgstr "Regresa el año del valor de fecha. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value"
+msgstr "valor"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value1, value2, ..."
+msgstr "valor1, valor2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "valueX, valueY"
+msgstr "valorX, valorY"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "index, value1, value2, ..."
+msgstr "indice, valor1, valor2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range"
+msgstr "rango"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, criteria"
+msgstr "rango, criterio"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "year, month, day"
+msgstr "año, mes, día"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "databaserange, fieldname, criteriarange"
+msgstr "rangobasedatos, nombrecampo, rangocriterio"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period [, factor]"
+msgstr "costo, recuperar, toda la vida, periodo [, factor]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "string1, string2 [, start]"
+msgstr "cadena1, cadena2 [, inicio]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [pv, [paytype]]"
+msgstr "tasa, n, pago, [pv, [tipopago]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, row, [rangelookup]"
+msgstr "valor, rango, fila, [rangodebusqueda]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "logical-expression, true-value, false-value"
+msgstr "expresión-logica, valor-verdadero, valor-falso"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, rownum, colnum"
+msgstr "rango, filannúmero, columnanúmero"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, [guess]"
+msgstr "range, [suponer]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, count"
+msgstr "texto, contar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, base"
+msgstr "valor, base"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, [rangelookup]"
+msgstr "valor, rango, [rangodebusqueda]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, start, length"
+msgstr "texto, iniciar, longitud"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, payment, pv, [fv, [paytype]]"
+msgstr "tasa, pago, pv, [tipopago]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, value1, value2, ..."
+msgstr "tasa, valor1, valor2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, pv, [fv, [paytype]]"
+msgstr "tasa, n, pv, [fv, [tipopago]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [fv, [paytype]]"
+msgstr "tasa, n, pago, [fv, [tipopago]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "n, payment, pv, [fv, [paytype, [guess]]]"
+msgstr "n, pago, pv, [fv, [tipopago, [suponer]]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, start, length, text2"
+msgstr "texto1, iniciar, longitud, texto2"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, [precision]"
+msgstr "valor, [precisión]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime"
+msgstr "costo, recuperar, toda la vida"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period"
+msgstr "costo, recuperar, toda la vida, periodo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, oldtext, newtext [, occurrence]"
+msgstr "texto1, textoviejo, textonuevo [, ocurrencia]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range1, criteria [, range2]"
+msgstr "rango1, criterio [, rango2]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "hour, minute, second"
+msgstr "hora, minuto, segundo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, col, [rangelookup]"
+msgstr "valor, rango, columnna, [rangodebusqueda]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date, [type]"
+msgstr "fecha, [tipo]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date"
+msgstr "fecha"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["all", "stat", "lookup", "datetime", "financial", "test", "math", Text]
+#msgstr ["todo", "estadistica", "buscar", "fechahora", "financiera", "prueba", "matemática", Texto]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "All"
+msgstr "Todo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Statistics"
+msgstr "Estadisticas"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Lookup"
+msgstr "Buscar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Date & Time"
+msgstr "Fecha & Hora"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Financial"
+msgstr "Financiera"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Test"
+msgstr "Prueba"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Math"
+msgstr "Matemáticas"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cells to Graph"
+msgstr "Células de Gráfico"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Graph"
+msgstr "Set celdas Para El Gráfico"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph Type"
+msgstr "Tipo de gráfico"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "filter:alpha(opacity=90);opacity:.9;"
+msgstr "filter: alpha (opacity = 90); opacity: .9;"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain"
+msgstr "Plain"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph"
+msgstr "Gráfico"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Pie Chart"
+msgstr "Gráfico Circular"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Help"
+msgstr "Ayuda"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal Bar"
+msgstr "Barras Horizontales"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical Bar"
+msgstr "Barras Verticales"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Line Chart"
+msgstr "Gráfico de Líneas"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plot Points"
+msgstr "Gráfico de Puntos"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown range name"
+msgstr "Nombre de rango desconocido"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hide Help"
+msgstr "Ayuda Ocultar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Max "
+msgstr "Max "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Min "
+msgstr "Min "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " OK "
+msgstr " OK "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Cancel]"
+msgstr "[Abbrechen]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "TRUE"
+msgstr "TRUE"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "FALSE"
+msgstr "FALSE"
+
diff --git a/po/fr.po b/po/fr.po
new file mode 100644
index 0000000..3f61ca0
--- /dev/null
+++ b/po/fr.po
@@ -0,0 +1,1479 @@
+# Copyright (C) 2010 THE PACKAGE"S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# olpc user <olpc@localhost.localdomain>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: SocialCalcActivity.activity\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-01-07 14:46+0000\n"
+"PO-Revision-Date: 2010-01-09 21:53+0530\n"
+"Last-Translator: Diksha<dksh.khatri@gmail.com>\n"
+"Language-Team: Hindi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: activity/activity.info:2
+msgid "SocialCalcActivity"
+msgstr "SocialCalcActivity"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:10
+#msgid "t"
+#msgstr "t"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:13
+msgid "Browser not supported. "
+msgstr "Navigateur non pris en charge."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:14
+msgid "Internal SocialCalc error (probably an internal bug):"
+msgstr "SocialCalc erreur interne (sans doute un bug interne):"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:20
+msgid "Unknown col type item"
+msgstr "Inconnu Point de type col"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:21
+msgid "Unknown row type item"
+msgstr "Inconnu rangée type d'élément"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:22
+msgid "Unknown line type"
+msgstr "Ligne de type inconnu"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:28
+msgid "Unknown cell type item"
+msgstr "Inconnu cellule type d'élément"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:36
+msgid "Unknown sheet command: "
+msgstr "Fiche de commande inconnu:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:37
+msgid "Unknown set coord command: "
+msgstr "Inconnu jeu de commandes coord:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:38
+msgid "Unknown command: "
+msgstr "Unknown command:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:42
+msgid "Circular reference to "
+msgstr "Circulaire référence à "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:52
+#msgid "padding:2px 2px 1px 2px;vertical-align:top;"
+#msgstr "padding: 2px 2px 1px 2px; vertical-align: top;"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:53
+msgid "normal normal"
+msgstr "normal normal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:54
+msgid "small"
+msgstr "petit"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:55
+msgid "Verdana,Arial,Helvetica,sans-serif"
+msgstr "Verdana, Arial, Helvetica, sans-serif"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:92
+msgid "Render Context must have a sheet object"
+msgstr "Render Contexte doit avoir un objet feuille de"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Executing..."
+msgstr "Exécution en cours ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Displaying..."
+msgstr "Afficher ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Ordering..."
+msgstr "Commande de ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating..."
+msgstr "Calcul en cours ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating... Loading Sheet..."
+msgstr "Calcul en cours ... Chargement Feuille ..."
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "doing server function "
+msgstr "faisant fonction de serveur"
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " in cell "
+msgstr "dans la cellule"
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculation start..."
+msgstr "Calcul de commencer ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SUM"
+msgstr "SOMME"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Multi-line text: Click icon on right to edit]"
+msgstr "[Multi-texte en ligne: Cliquez sur l'icône sur le droit d'éditer]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function "
+msgstr "Fonction inconnue"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane vertically"
+msgstr "Faites glisser pour verrouiller le volet vertica"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane horizontally"
+msgstr "Faites glisser pour verrouiller le volet horizontal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Center"
+msgstr "Aligner au centre"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Aligner à gauche"
+msgstr "Alinear a la izquierda "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Right"
+msgstr "Aligner à droite"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Alignment"
+msgstr "Alignement"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit"
+msgstr "Vérification"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit Trail This Session"
+msgstr "Piste de vérification de cette session"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto"
+msgstr "Auto"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto Sum"
+msgstr "Auto Sum"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto w/ commas"
+msgstr "Auto w / virgules"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Automatic"
+msgstr "Automatique"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Background"
+msgstr "Arrière-plan"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold"
+msgstr "Bold"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold &amp; Italics"
+msgstr "Bold & Italique"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold Italic"
+msgstr "Bold Italic"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders"
+msgstr "Borders"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders Off"
+msgstr "Hors frontières"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders On"
+msgstr "Frontières sur"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom"
+msgstr "bas"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom Border"
+msgstr "Bas de frontières"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CELL SETTINGS"
+msgstr "PARAMETRES DE PILE"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CSV format"
+msgstr "Format CSV"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cancel"
+msgstr "Annuler"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Category"
+msgstr "catégorie"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Center"
+msgstr "Centre"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear"
+msgstr "Clair"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear SocialCalc Clipboard"
+msgstr "Clair SocialCalc Presse-papiers"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clipboard"
+msgstr "Presse-papiers"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Color"
+msgstr "Couleur"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Column"
+msgstr "Colonne"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Comment"
+msgstr "Commentaire"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Copy"
+msgstr "Copier"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Custom"
+msgstr "Personnalisé"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cut"
+msgstr "couper"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default"
+msgstr "Défaut"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Alignment"
+msgstr "Défaut, l'alignement"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Column Width"
+msgstr "Largeur de colonne par défaut"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Font"
+msgstr "Police par défaut"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Format"
+msgstr "Format par défaut"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Padding"
+msgstr "Remplissage par défaut"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete"
+msgstr "Dlete"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Column"
+msgstr "Supprimer la colonne"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Contents"
+msgstr "Supprimer le contenu"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Row"
+msgstr "Supprimer la ligne"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Description"
+msgstr "Description"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Display Clipboard in"
+msgstr "Annonce Presse-papiers en"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Down"
+msgstr "Vers le bas"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Edit"
+msgstr "Modifier"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Existing Names"
+msgstr "Noms actuels"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Family"
+msgstr "Famille"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Down"
+msgstr "Remplissage vers le bas"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Right"
+msgstr "Remplissage vers la droite"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Font"
+msgstr "Font"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Format"
+msgstr "Format"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula"
+msgstr "Formule"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Function List"
+msgstr "Liste Functon"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Functions"
+msgstr "Fonctions"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Grid"
+msgstr "Grid"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hidden"
+msgstr "Oculto"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal"
+msgstr "Horizontal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Column"
+msgstr "Insérer une colonne"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Row"
+msgstr "Insérer une ligne"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Italic"
+msgstr "Italique"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Last Sort"
+msgstr "Dernière mise à trier"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left"
+msgstr "Gauche"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left Border"
+msgstr "La bordure gauche"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link"
+msgstr "Lien"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link Input Box"
+msgstr "Lien Boîte de saisie"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "List"
+msgstr "Liste"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Load SocialCalc Clipboard With This"
+msgstr "Load SocialCalc presse-papiers avec cette"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Major Sort"
+msgstr "Major Trier"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Manual"
+msgstr "Manuel"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Merge Cells"
+msgstr "Fusionner des cellules"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Middle"
+msgstr "Moyen"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Minor Sort"
+msgstr "Axe Trier"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Insert"
+msgstr "Déplacez Insérer"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Paste"
+msgstr "Déplacez Coller"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Multi-line Input Box"
+msgstr "Multi-line Boîte de saisie"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Name"
+msgstr "Nom"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Names"
+msgstr "Noms"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "No padding"
+msgstr "Pas de remplissage"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Normal"
+msgstr "Normal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number"
+msgstr "Nombre"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number Horizontal"
+msgstr "Nombre Horizontal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "OK"
+msgstr "OK"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Padding"
+msgstr "relleno"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Page Name"
+msgstr "Nom de la page"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste"
+msgstr "Coller"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste Formats"
+msgstr "Coller Formats"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain Text"
+msgstr "Plain Text"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalc"
+msgstr "Recalculer"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalculation"
+msgstr "Nouveau calcul"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " Redo"
+msgstr "Refaire"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right"
+msgstr "Droit"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right Border"
+msgstr "La bordure de droite"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SHEET SETTINGS"
+msgstr "FICHE DE REGLAGES"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save"
+msgstr "sauver"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save to"
+msgstr "Enregistrer pour"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cell Contents"
+msgstr "Set Contenu des cellules"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Sort"
+msgstr "Ensemble des cellules à Trier"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Value To"
+msgstr "Réglez la valeur à"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set to Link format"
+msgstr "Set Link Format"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set/Clear Move From"
+msgstr "Set / Clear Passer de lae"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Cell Settings"
+msgstr "Afficher Cell Paramètres"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Sheet Settings"
+msgstr "Voir la fiche de paramètres"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show in new browser window"
+msgstr "Afficher dans nouvelle fenêtre de navigateur "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Size"
+msgstr "Taille "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SocialCalc-save format"
+msgstr "SocialCalc-format de sauvegarde"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort"
+msgstr "Trier"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort Cells"
+msgstr "Trier les cellules"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Swap Colors"
+msgstr "Swap Colors"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Tab-delimited format"
+msgstr "Tab-format défin"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text"
+msgstr "Texte"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text Horizontal"
+msgstr "Texte horizontal "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "This is a<br>sample"
+msgstr "Il s'agit d'un échantillon <br>"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top"
+msgstr "Haut"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top Border"
+msgstr "Top Border"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "UNDONE STEPS"
+msgstr "UNDONE ÉTAPES"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "URL"
+msgstr "URL"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Undo"
+msgstr "Undo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unmerge Cells"
+msgstr "Unmerge Cells"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Up"
+msgstr "Vers le haut"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Value"
+msgstr "Valeur"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical"
+msgstr "Vertical"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Workspace"
+msgstr "Workspace"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[New]"
+msgstr "[Nouveau]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[None]"
+msgstr "[Aucun]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[select range]"
+msgstr "[sélectionnez une plage]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
+#msgstr [ "Dimanche", "Lundi", "mardi", "mercredi", "Jeudi", "Vendredi", "Samedi"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
+#msgstr [ "Sun", "Mon", "Mar", "Mar", "Jeu", "Ven", "Sat"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["January", "February", "March", "April", "May", "June", "July", "August", "September","October", "November", "December"]
+#msgstr ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+#msgstr [ "Ene", "Feb", "Mar", "Avr", "Mai", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "AM"
+#msgstr "AM"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "A"
+#msgstr "Un"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "PM"
+#msgstr "PM"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "P"
+#msgstr "P"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed number exponent"
+msgstr "Mal formés exposant nombre"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unexpected character in formula"
+msgstr "Caractère inattendu dans la formule"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed string"
+msgstr "Chaîne de caractères mal formés"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed special value"
+msgstr "Mal formés valeur particulière"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula (two operators inappropriately in a row)"
+msgstr "Erreur dans la formule (deux opérateurs de façon inappropriée dans une rangée)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing open parenthesis in list with comma(s)."
+msgstr "Missing parenthèse ouverte dans la liste avec la virgule (s)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Closing parenthesis without open parenthesis. "
+msgstr "Clôture parenthèse sans parenthèse ouverte."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing close parenthesis."
+msgstr "Missing parenthèse fermante."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing operand."
+msgstr "Missing opérande"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula."
+msgstr "Erreur dans la formule"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error value in formula"
+msgstr "Valeur de l'erreur dans la formule"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula resulting in bad value"
+msgstr "Erreur dans la formule qui en résulte dans la mauvaise valeur"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in range value:"
+msgstr "Résultats de la formule de la valeur gamme:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in an bad numeric value"
+msgstr "Formule se traduit par une valeur numérique mauvais"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Numeric overflow"
+msgstr "Numeric overflow"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet unavailable:"
+msgstr "Fiche disponible:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cell reference missing when expected."
+msgstr "Cell référence manquante au moment prévu."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet name missing when expected."
+msgstr "Nom de feuille manquante au moment prévu."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Circular name reference to name"
+msgstr "Circulaire référence de nom pour ne citer"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown name"
+msgstr "Nom inconnu"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Incorrect arguments to function"
+msgstr "Arguments incorrects de fonctionner"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function"
+msgstr "Fonction inconnue"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LN argument must be greater than 0"
+msgstr "LN argument doit être supérieure à 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG10 argument must be greater than 0"
+msgstr "LOG10 argument doit être supérieure à 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG second argument must be numeric greater than 0"
+msgstr "LOG deuxième argument doit être un nombre supérieur à 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG first argument must be greater than 0"
+msgstr "LOG premier argument doit être supérieure à 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "ROUND second argument must be numeric"
+msgstr "ROUND deuxième argument doit être numérique"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "DDB life must be greater than 1"
+msgstr "DDB vie doit être supérieur à 1"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SLN life must be greater than 1"
+msgstr "SLN vie doit être supérieur à 1"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Absolute value function. "
+msgstr "Une fonction de valeur absolue. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arccosine function. "
+msgstr "Fonction trigonométrique arccosinus."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if all arguments are true. "
+msgstr "Vrai si tous les arguments sont vrais"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arcsine function. "
+msgstr "Fonction trigonométrique arcsinus. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arctan function. "
+msgstr "Trigonométriques fonction arctan."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arc tangent function (result is in radians). "
+msgstr "Fonction trigonométrique arc tangent (le résultat est en radians). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values. "
+msgstr "Les moyennes des valeurs. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value specified by the index. The values may be ranges of cells. "
+msgstr "Renvoie la valeur spécifiée par l'index. Les valeurs de mai être des plages de cellules. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of columns in the range. "
+msgstr "Retourne le nombre de colonnes dans la gamme. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric cosine function (value is in radians). "
+msgstr "Trigonométriques cosine fonction (la valeur est en radians)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error. "
+msgstr "Compte le nombre de valeurs numériques, pas vierge, le texte, ou d'erreurs. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values. "
+msgstr "Compte le nombre de valeurs non vides. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of blank values. (Note: '' is not blank.) "
+msgstr "Compte le nombre de valeurs vides. (Note:''n'est pas vierge.) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of number of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). "
+msgstr "Compte le nombre de nombre de cellules dans la gamme qui répondent aux critères. Les critères de mai soit une valeur ( 'x', 15, 1 +3) ou un test (> 25). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the appropriate date value given numbers for year, month, and day. For example: DATE(2006,2,1) for February 1, 2006. Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "Retourne la valeur de la date appropriée chiffres donnés pour l'année, le mois et le jour. Par exemple: DATE (2006,2,1) pour 1 Février 2006. Note: Dans ce programme, jour 1 étant Décembre 31, 1899 et l'année 1900 n'est pas une année bissextile. Certains programmes utilisent Janvier 1, 1900, comme le jour 1 et de traiter 1900 comme une année bissextile. Dans les deux cas, cependant, les dates à partir du 1er Mars 1900, sont les mêmes. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values in the specified field in records that meet the criteria. "
+msgstr "Les valeurs moyennes dans le champ spécifié dans les dossiers qui répondent aux critères. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of month for a date value. "
+msgstr "Renvoie le jour du mois pour une valeur de date. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error, in the specified field in records that meet the criteria. "
+msgstr "Compte le nombre de valeurs numériques, pas vierge, le texte, ou d'erreur, dans le champ spécifié dans les dossiers qui répondent aux critères. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values in the specified field in records that meet the criteria. "
+msgstr "Compte le nombre de valeurs non vides dans le champ spécifié dans les dossiers qui répondent aux critères. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at the given period of time (the default factor is 2 for double-declining balance). "
+msgstr "Retourne le montant de l'amortissement à la période de temps donnée (le facteur de défaut: 2 pour l'équilibre double-déclin). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in radians into degrees. "
+msgstr "Convertit la valeur en radians en degrés. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value of the specified field in the single record that meets the criteria. "
+msgstr "Retourne la valeur du champ spécifié dans l'enregistrement unique qui répond aux critères. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Retourne le maximum des valeurs numériques dans le domaine défini par des dossiers qui répondent aux critères. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values in the specified field in records that meet the criteria. "
+msgstr "Renvoie le résultat de la multiplication des valeurs numériques dans le domaine défini par des dossiers qui répondent aux critères. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Retourne l'écart type des valeurs numériques dans le champ spécifié dans les dossiers qui répondent aux critères. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Retourne l'écart type des valeurs numériques dans le domaine défini par des dossiers qui répondent aux critères. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Retourne la somme des valeurs numériques dans le champ spécifié dans les dossiers qui répondent aux critères. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Retourne la variance de l'échantillon des valeurs numériques dans le champ spécifié dans les dossiers qui répondent aux critères. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Retourne la variance des valeurs numériques dans le champ spécifié dans les dossiers qui répondent aux critères. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest even integer. "
+msgstr "Arrondit la valeur en importance au plus proche entier pair. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the values are exactly the same, including case, type, etc. "
+msgstr "Retourne true si les valeurs sont exactement les mêmes, y compris le dossier, type, etc "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns e raised to the value power. "
+msgstr "Retourne e élevé à la puissance de valeur."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns factorial of the value. "
+msgstr "Factorielle de la valeur des retours. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value false. "
+msgstr "Renvoie la valeur logique faux. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the starting position within string2 of the first occurrence of string1 at or after start. If start is omitted, 1 is assumed. "
+msgstr "Retourne la position de départ dans chaîne_2 de la première occurrence de chaine1 à ou après son démarrage. Si start est omis, 1 est pris en charge. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the future value of repeated payments of money invested at the given rate for the specified number of periods, with optional present value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Renvoie la valeur future des paiements répétés de fonds investis au taux donné pour le nombre déterminé de périodes, avec la valeur actuelle en option (par défaut 0) et le type de paiement (par défaut 0 = en fin de période, 1 = début de la période). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the row offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. "
+msgstr "Recherchez la valeur correspondant à la valeur donnée dans la gamme et retourner la valeur correspondante dans la cellule spécifiée par la ligne de décalage. Si rangelookup est le 1 (par défaut) et pas 0, le match si dans les crochets numérique (match <= valeur) au lieu de correspondance exacte. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the hour portion of a time or date/time value. "
+msgstr "Renvoie la partie heure d'une heure ou la date / heure. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Results in true-value if logical-expression is TRUE or non-zero, otherwise results in false-value. "
+msgstr "Les résultats en valeur réelle, si l'expression logique est VRAI ou non nulle, sinon les résultats de la valeur faux. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns a cell or range reference for the specified row and column in the range. If range is 1-dimensional, then only one of rownum or colnum are needed. If range is 2-dimensional and rownum or colnum are zero, a reference to the range of just the specified column or row is returned. You can use the returned reference value in a range, e.g., sum(A1:INDEX(A2:A10,4)). "
+msgstr "Renvoie une cellule ou une plage de référence pour la ligne indiquée et la colonne de la gamme. Si la portée est de dimension 1, alors une seule ou de rownum colnum sont nécessaires. Si la portée est de 2 dimensions et rownum ou colnum sont nuls, une référence à la portée limitée à la colonne spécifiée ou à la ligne n'est retournée. Vous pouvez utiliser la valeur retournée de référence dans une plage, par exemple, sum (A1: INDEX (A2: A10, 4)). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value rounded down to the nearest integer (towards -infinity). "
+msgstr "Retourne la valeur arrondie à l'entier le plus proche (vers l'infini). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the interest rate at which the cash flows in the range have a net present value of zero. Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "Retourne le taux d'intérêt auquel les flux de trésorerie de la gamme ont une valeur actuelle nette égale à zéro. Utilise un processus itératif, qui renvoie # NUM! si elle ne converge pas d'erreur. Il y mai être plus d'une solution possible. Fournir la valeur estimée facultative mai aider dans certaines situations où elle ne converge pas ou trouve une solution appropriée (la proposition par défaut est de 10%). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is a reference to a blank cell. "
+msgstr "Retourne true si la valeur est une référence à une cellule vide. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error but not NA. "
+msgstr "Retourne true si la valeur est de l'erreur type, mais pas NA. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error. "
+msgstr "Retourne true si la valeur est de l'erreur type. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Logical (true/false). "
+msgstr "Retourne true si la valeur est de type logique (vrai / faux). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is the error type NA. "
+msgstr "Retourne true si la valeur est le type d'erreur NA. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is not of type Text. "
+msgstr "Retourne true si la valeur n'est pas de type Texte. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Number (including logical values). "
+msgstr "Retourne true si la valeur est de type Number (y compris les valeurs logiques). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Text. "
+msgstr "Retourne true si la valeur est de type Texte. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value. If count is omitted, 1 is assumed. "
+msgstr "Retourne le nombre spécifié de caractères à partir de la valeur du texte. Si count est omis, 1 est pris en charge. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of characters in the text value. "
+msgstr "Retourne le nombre de caractères dans la valeur du texte. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the natural logarithm of the value. "
+msgstr "Retourne le logarithme naturel de la valeur. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logarithm of the value using the specified base. "
+msgstr "Retourne le logarithme de la valeur en utilisant la base spécifiée. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the base 10 logarithm of the value. "
+msgstr "Retourne le logarithme en base 10 de la valeur. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all uppercase characters converted to lowercase. "
+msgstr "Retourne la valeur du texte avec tous les caractères majuscules convertis en minuscules. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return position (the first is 1) in that range. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. If rangelookup is -1, act like 1 but the bracket is match>=value. "
+msgstr "Recherchez la valeur correspondant à la valeur donnée dans la gamme et la position de rappel (le premier est 1) dans cette gamme. Si rangelookup est le 1 (par défaut) et pas 0, le match si dans les crochets numérique (match <= valeur) au lieu de correspondance exacte. Si rangelookup est de -1, agissent comme 1, mais le support est match> = valeur. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values. "
+msgstr "Retourne le maximum des valeurs numériques. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the specified position. "
+msgstr "Retourne le nombre spécifié de caractères à partir de la valeur du texte à partir de la position spécifiée. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minimum of the numeric values. "
+msgstr "Retourne le minimum des valeurs numériques. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minute portion of a time or date/time value. "
+msgstr " Retourne la partie infime d'une heure ou la date / heure. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the remainder of the first value divided by the second. "
+msgstr "Retourne le reste de la première valeur divisée par le second. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the month part of a date value. "
+msgstr "Renvoie la partie mois d'une valeur de date. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value if it is a numeric value otherwise an error. "
+msgstr "Retourne la valeur si elle est une valeur numérique sinon une erreur. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the #N/A error value which propagates through most operations. "
+msgstr "Renvoie l'erreur # N / A valeur d'erreur qui se propage à travers la plupart des opérations. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns FALSE if value is true, and TRUE if it is false. "
+msgstr "Retourne FALSE si la valeur est vrai, et TRUE si elle est fausse. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date/time. "
+msgstr "Retourne la date / l'heure actuelle. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of periods at which payments invested each period at the given rate with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period) has the given present value. "
+msgstr "Retourne le nombre de périodes pendant lesquelles les paiements ont investi chaque période au taux donné avec la valeur future optionnels (par défaut 0) et le type de paiement (par défaut 0 = en fin de période, 1 = début de la période) est la valeur actuelle donnée. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the net present value of cash flows (which may be individual values and/or ranges) at the given rate. The flows are positive if income, negative if paid out, and are assumed at the end of each period. "
+msgstr "Renvoie la valeur actuelle nette des flux de trésorerie (qui mai être des valeurs individuelles et / ou des plages), au taux donné. Les flux sont positifs, si le revenu, négatif si payées, et sont pris en charge à la fin de chaque période. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest odd integer. "
+msgstr "Arrondit la valeur en importance au plus proche entier impair. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if any argument is true "
+msgstr "Vrai si un des arguments est vrai "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "The value 3.1415926... "
+msgstr "La valeur 3.1415926 ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of each payment that must be invested at the given rate for the specified number of periods to have the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Retourne le montant de chaque paiement qui doit être investi au taux donné pour le nombre déterminé de périodes d'avoir la valeur actuelle spécifié, avec la valeur future optionnels (par défaut 0) et le type de paiement (par défaut 0 = en fin de période, 1 = début de la période). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the first value raised to the second value power. "
+msgstr "Retourne la première valeur élevée à la puissance seconde valeur. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values. "
+msgstr "Renvoie le résultat de la multiplication des valeurs numériques. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with the first letter of each word converted to uppercase and the others to lowercase. "
+msgstr "Retourne la valeur du texte avec la première lettre de chaque mot converti en majuscules et les autres en minuscules. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the present value of the given number of payments each invested at the given rate, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Retourne la valeur actuelle du nombre donné de paiements chacune investi au taux donné, avec la valeur future optionnels (par défaut 0) et le type de paiement (par défaut 0 = en fin de période, 1 = début de la période). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in degrees into radians. "
+msgstr "Convertit la valeur en degrés en radians. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the rate at which the given number of payments each invested at the given rate has the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "Renvoie la vitesse à laquelle le nombre donné de paiements chaque investi au taux donné a la valeur spécifiée, avec une valeur future optionnels (par défaut 0) et le type de paiement (par défaut 0 = en fin de période, 1 = début de la période). Utilise un processus itératif, qui renvoie # NUM! si elle ne converge pas d'erreur. Il y mai être plus d'une solution possible. Fournir la valeur estimée facultative mai aider dans certaines situations où elle ne converge pas ou trouve une solution appropriée (la proposition par défaut est de 10%). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the specified number of characters starting from the specified position replaced by text2. "
+msgstr "Retours text1 avec le nombre spécifié de caractères à partir de la position spécifiée remplacé par text2. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text repeated the specified number of times. "
+msgstr "Retourne le texte répété le nombre de fois spécifié. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the end. If count is omitted, 1 is assumed. "
+msgstr "Retourne le nombre spécifié de caractères à partir de la valeur du texte à partir de la fin. Si count est omis, 1 est pris en charge. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value to the specified number of decimal places. If precision is negative, then round to powers of 10. The default precision is 0 (round to integer). "
+msgstr "Arrondit la valeur au nombre spécifié de décimales. Si la précision est négatif, puis autour des puissances de 10. La précision par défaut est 0 (rond en entier). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of rows in the range. "
+msgstr "Retourne le nombre de lignes dans la gamme. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the second portion of a time or date/time value (truncated to an integer). "
+msgstr "Retourne la seconde portion d'une heure ou la date / heure (arrondie). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric sine function (value is in radians) "
+msgstr "Trigonométriques sinus fonction (la valeur est en radians) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at each period of time using the straight-line method. "
+msgstr "Retourne le montant de la dépréciation à chaque période de temps en utilisant la méthode de l'amortissement linéaire. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Square root of the value "
+msgstr "La racine carrée de la valeur "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values. "
+msgstr "Retourne l'écart type des valeurs numériques. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values. "
+msgstr "Retourne l'écart type des valeurs numériques. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the all occurrences of oldtext replaced by newtext. If occurrence is present, then only that occurrence is replaced. "
+msgstr "Retours text1 avec les toutes les occurrences de oldtext remplacé par newText. Si l'accident est présent, alors que cet incident est remplacé. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Adds the numeric values. The values to the sum function may be ranges in the form similar to A1:B5. "
+msgstr "Ajoute les valeurs numériques. Les valeurs de la fonction SOMME mai être des plages dans la forme semblable à A1: B5. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sums the numeric values of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). If range2 is present, then range1 is tested and the corresponding range2 value is summed. "
+msgstr "La somme des valeurs numériques des cellules de la plage qui répondent aux critères. Les critères de mai soit une valeur ( 'x', 15, 1 +3) ou un test (> 25). Si Rangée2 est présent, alors range1 est contrôlé et la valeur correspondante Rangée2 est résumée. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Depreciation by Sum of Year's Digits method. "
+msgstr "Amortissement par la somme des chiffres méthode de l'An. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value or else a null string. "
+msgstr "Retourne la valeur de texte ou bien une chaîne nulle. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric tangent function (value is in radians) "
+msgstr "Trigonométrique tangente fonction (la valeur est en radians) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the time value given the specified hour, minute, and second. "
+msgstr "Retourne la valeur de temps étant donné l'heure spécifiée, minute et seconde. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "Returns the current date (an integer). Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+#msgstr "Renvoie la date actuelle (un entier). Note: Dans ce programme, jour 1 étant Décembre 31, 1899 et l'année 1900 n'est pas une année bissextile. Certains programmes utilisent Janvier 1, 1900, comme le jour 1 et de traiter 1900 comme une année bissextile. Dans les deux cas, cependant, les dates à partir du 1er Mars 1900, sont les mêmes. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with leading, trailing, and repeated spaces removed. "
+msgstr "Retourne la valeur du texte de diriger, de suivi, des espaces multiples et enlevé. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value true. "
+msgstr "Renvoie la valeur logique vrai. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Truncates the value to the specified number of decimal places. If precision is negative, truncate to powers of 10. "
+msgstr "Tronque la valeur pour le nombre spécifié de décimales. Si la précision est négatif, tronquer des puissances de 10. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all lowercase characters converted to uppercase. "
+msgstr "Retourne la valeur du texte avec tous les caractères minuscules convertis en majuscules. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts the specified text value into a numeric value. Various forms that look like numbers (including digits followed by %, forms that look like dates, etc.) are handled. This may not handle all of the forms accepted by other spreadsheets and may be locale dependent. "
+msgstr "Convertit la valeur du texte spécifié dans une valeur numérique. Diverses formes qui ressemblent à des numéros (y compris les chiffres suivis%, des formes qui ressemblent à des dates, etc) sont traités. Cette mai ne pas gérer toutes les formes acceptées par d'autres tableurs et mai être dépend de la locale. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values. "
+msgstr "Renvoie la variance de l'échantillon des valeurs numériques. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values. "
+msgstr "Retourne la variance des valeurs numériques. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the column offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match>=value) instead of exact match. "
+msgstr "Recherchez la valeur correspondant à la valeur donnée dans la gamme et retourner la valeur correspondante dans la cellule spécifiée par la colonne de décalage. Si rangelookup est le 1 (par défaut) et pas 0, le match si dans les crochets numérique (match> = valeur) au lieu de correspondance exacte. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of week specified by the date value. If type is 1 (the default), Sunday is day and Saturday is day 7. If type is 2, Monday is day 1 and Sunday is day 7. If type is 3, Monday is day 0 and Sunday is day 6. "
+msgstr "Retourne le jour de la semaine spécifiée par la valeur de date. Si le type est de 1 (par défaut), le dimanche est le jour et le samedi est jour 7. Si le type est de 2, lundi étant le jour 1 et dimanche le jour 7. Si le type est 3, le lundi est le jour 0 et le dimanche est le jour 6. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the year part of a date value. "
+msgstr "Retourne la partie de l'année d'une valeur de date. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value"
+msgstr "valeur"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value1, value2, ..."
+msgstr "value1, value2, ... "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "valueX, valueY"
+msgstr "valueX, valueY "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "index, value1, value2, ..."
+msgstr "index, value1, value2, ... "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range"
+msgstr "range"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, criteria"
+msgstr "gamme,critères "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "year, month, day"
+msgstr "année, mois, jour"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "databaserange, fieldname, criteriarange"
+msgstr "databaserange, fieldname, criteriarange "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period [, factor]"
+msgstr "coût, récupération, durée de vie, période [, facteur] "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "string1, string2 [, start]"
+msgstr "string1, string2 [, start] "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [pv, [paytype]]"
+msgstr "taux, n, le paiement, [pv, [paytype]] "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, row, [rangelookup]"
+msgstr "valeur, gamme, ligne, [rangelookup] "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "logical-expression, true-value, false-value"
+msgstr "logiques d'expression, la valeur vraie, valeur fausse-"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, rownum, colnum"
+msgstr "gamme, rownum, colnum "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, [guess]"
+msgstr "gamme, [guess] "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, count"
+msgstr "text, count"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, base"
+msgstr "valeur, base "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, [rangelookup]"
+msgstr "valeur, la portée, [rangelookup] "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, start, length"
+msgstr "texte, début, longueur "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, payment, pv, [fv, [paytype]]"
+msgstr "taux, le paiement, pv, [fv, [paytype]] "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, value1, value2, ..."
+msgstr "taux, valeur1, valeur2, ... "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, pv, [fv, [paytype]]"
+msgstr "taux, n, pv, [fv, [paytype]] "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [fv, [paytype]]"
+msgstr "taux, n, le paiement, [fv, [paytype]] "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "n, payment, pv, [fv, [paytype, [guess]]]"
+msgstr "n, le paiement, pv, [fv, [paytype, [guess]]] "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, start, length, text2"
+msgstr "text1, début, longueur, Text2 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, [precision]"
+msgstr "valeur, [précision] "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime"
+msgstr "coût, récupération, durée de vie "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period"
+msgstr "coût, récupération, durée de vie, période "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, oldtext, newtext [, occurrence]"
+msgstr "text1, oldtext, newtext [, événement] "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range1, criteria [, range2]"
+msgstr "range1, les critères [, Rangée2] "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "hour, minute, second"
+msgstr "heure, minute, seconde "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, col, [rangelookup]"
+msgstr "valeur, la portée, col, [rangelookup] "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date, [type]"
+msgstr "date, [type]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date"
+msgstr "date"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["all", "stat", "lookup", "datetime", "financial", "test", "math", Text]
+#msgstr ["all", "stat", "rechercher", "datetime", "financière", "test", "math", texte]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "All"
+msgstr "Tous"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Statistics"
+msgstr "Statistiques"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Lookup"
+msgstr "Lookup "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Date & Time"
+msgstr "Date & Heure "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Financial"
+msgstr "Financière"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Test"
+msgstr "Test"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Math"
+msgstr "Math"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cells to Graph"
+msgstr "Cellules à Graph"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Graph"
+msgstr "Cels Set to Graph"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph Type"
+msgstr "Type de graphique"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "filter:alpha(opacity=90);opacity:.9;"
+msgstr "filter: alpha (opacity = 90); opacity: .9; "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain"
+msgstr "Plain"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph"
+msgstr "Graphique"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Pie Chart"
+msgstr "Pie Chart"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Help"
+msgstr "Aider"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal Bar"
+msgstr "Barre fixe"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical Bar"
+msgstr "Barre vertical"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Line Chart"
+msgstr "Graphique linéaire"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plot Points"
+msgstr "Plot Points"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown range name"
+msgstr "Nom de plage inconnu"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hide Help"
+msgstr "Masquer l'aide"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Max "
+msgstr "Max "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Min "
+msgstr "Min "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " OK "
+msgstr " OK "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date (an integer). Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "Renvoie la date actuelle (un entier). Note: Dans ce programme, le jour «1» est Décembre 31, 1899 et l'année 1900 n'est pas une année bissextile. Certains programmes utilisent Janvier 1, 1900, comme le jour 1 et de traiter 1900 comme une année bissextile. Dans les deux cas, cependant, les dates à partir du 1er Mars 1900, sont les mêmes. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Cancel]"
+msgstr "[Annuler]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "TRUE"
+msgstr "TRUE"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "FALSE"
+msgstr "FAUX "
+
diff --git a/po/hi.po b/po/hi.po
new file mode 100644
index 0000000..46ada97
--- /dev/null
+++ b/po/hi.po
@@ -0,0 +1,1480 @@
+#"Project-Id-Version: \n"
+#"POT-Creation-Date: \n"
+#"PO-Revision-Date: \n"
+#"Last-Translator: vijit <vijit_s@yahoo.com>\n"
+#"Language-Team: Hindi\n"
+#"MIME-Version: 1.0\n"
+#"Content-Type: text/plain; charset=utf-8\n"
+#"Content-Transfer-Encoding: 8bit\n"
+
+#: activity/activity.info:2
+msgid "SocialCalcActivity"
+msgstr "SocialCalcActivity"
+
+#msgid "t"
+#msgstr "टी"
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:10
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:13
+msgid "Browser not supported. "
+msgstr "बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤° समरà¥à¤¥à¤¿à¤¤ नहीं है"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:14
+msgid "Internal SocialCalc error (probably an internal bug):"
+msgstr "आंतरिक सोशलकेलà¥à¤• तà¥à¤°à¥à¤Ÿà¤¿ (शायद à¤à¤• आंतरिक बग):"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:20
+msgid "Unknown col type item"
+msgstr "अजà¥à¤žà¤¾à¤¤ कौलम पà¥à¤°à¤•à¤¾à¤° के आइटम"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:21
+msgid "Unknown row type item"
+msgstr "अजà¥à¤žà¤¾à¤¤ पंकà¥à¤¤à¤¿ पà¥à¤°à¤•à¤¾à¤° के आइटम"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:22
+msgid "Unknown line type"
+msgstr "?अजà¥à¤žà¤¾à¤¤ लाइन पà¥à¤°à¤•à¤¾à¤°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:28
+msgid "Unknown cell type item"
+msgstr "अजà¥à¤žà¤¾à¤¤ सेल पà¥à¤°à¤•à¤¾à¤° आइटम"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:36
+msgid "Unknown sheet command: "
+msgstr "अजà¥à¤žà¤¾à¤¤ पतà¥à¤°à¤• कमांड: "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:37
+msgid "Unknown set coord command: "
+msgstr "अजà¥à¤žà¤¾à¤¤ सेट कौरà¥à¤¡ कमांड: "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:38
+msgid "Unknown command: "
+msgstr "अजà¥à¤žà¤¾à¤¤ आदेश: "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:42
+msgid "Circular reference to "
+msgstr "परिपतà¥à¤° के लिठसंदरà¥à¤­"
+
+#msgid "30"
+#msgstr "30"
+#msgid "cell_"
+#msgstr "सेल_"
+#msgid "padding:2px 2px 1px 2px;vertical-align:top;"
+#msgstr "पेढिंग: 2पीà¤à¤•à¥à¤¸ 2पीà¤à¤•à¥à¤¸ 2पीà¤à¤•à¥à¤¸ : 1पीà¤à¤•à¥à¤¸ ; ऊरà¥à¤§à¥à¤µà¤¾à¤§à¤°-à¤à¤²à¤¾à¤‡à¤¨: शीरà¥à¤·;"
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:46
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:48
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:52
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:53
+msgid "normal normal"
+msgstr "सामानà¥à¤¯ सामानà¥à¤¯ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:54
+msgid "small"
+msgstr "छोटे "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Displaying..."
+msgstr "पà¥à¤°à¤¦à¤°à¥à¤¶à¤¿à¤¤ ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Ordering..."
+msgstr "आदेश ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating..."
+msgstr "गिना जा रहा है ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating... Loading Sheet..."
+msgstr "गिना जा रहा है ... शीट लोड हो रहा है ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "doing server function "
+msgstr "कर सरà¥à¤µà¤° समारोह "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " in cell "
+msgstr "सेल में"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculation start..."
+msgstr "गणना शà¥à¤°à¥‚ ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SUM"
+msgstr "सम"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Multi-line text: Click icon on right to edit]"
+msgstr "[मलà¥à¤Ÿà¥€ लाइन पाठ: संपादित करना ठीक पर कà¥à¤²à¤¿à¤• करें आइकन]"
+
+#msgid "fontSize:small;fontStyle:italic;padding:2px 10px 1px 2px;cursor:default;"
+#msgstr "फ़ोंटसाईज़: छोटे; फ़ोंटइसटाईल तिरछा:; padding: 2पीà¤à¤•à¥à¤¸ 10पीà¤à¤•à¥à¤¸ 2पीà¤à¤•à¥à¤¸: 1पीà¤à¤•à¥à¤¸; करà¥à¤¸à¤°: डिफ़ॉलà¥à¤Ÿ;"
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function "
+msgstr "अजà¥à¤žà¤¾à¤¤ समारोह"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane vertically"
+msgstr "खींचें फलक बंद करने खड़ी"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane horizontally"
+msgstr "खींचें फलक ताला को कà¥à¤·à¥ˆà¤¤à¤¿à¤œ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Center"
+msgstr "कà¥à¤°à¤®à¤¬à¤¦à¥à¤§à¤¬à¥€à¤šà¤®à¥‡à¤‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Left"
+msgstr "बायाà¤à¤ªà¤‚कà¥à¤¤à¤¿à¤¬à¤¦à¥à¤§à¤•à¤°à¥‡à¤‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Right"
+msgstr "दायाà¤à¤ªà¤‚कà¥à¤¤à¤¿à¤¬à¤¦à¥à¤§à¤•à¤°à¥‡à¤‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Alignment"
+msgstr "संरेखण"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit"
+msgstr "लेखा परीकà¥à¤·à¤¾"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit Trail This Session"
+msgstr "लेखा परीकà¥à¤·à¤¾ टà¥à¤°à¤¾à¤à¤² इस सतà¥à¤°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto"
+msgstr "ऑटो"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto Sum"
+msgstr "ऑटो जोड़"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto w/ commas"
+msgstr "ऑटो डबलà¥à¤¯à¥‚ / अलà¥à¤ªà¤µà¤¿à¤°à¤¾à¤®"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Automatic"
+msgstr "सà¥à¤µà¤¤:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Background"
+msgstr "पृषà¥à¤ à¤­à¥‚मि"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold"
+msgstr "बोलà¥à¤¡"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold &amp; Italics"
+msgstr "बोलà¥à¤¡ और तिरà¥à¤›à¤¾"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold Italic"
+msgstr "बोलà¥à¤¡ इटैलिक"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders"
+msgstr "सीमा"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders Off"
+msgstr "बंद सीमा"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders On"
+msgstr "सीमाओं पर"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom"
+msgstr "तली"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom Border"
+msgstr "नीचे सीमा"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CELL SETTINGS"
+msgstr "सेल सà¥à¤¥à¤¾à¤ªà¤¨ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CSV format"
+msgstr "सीà¤à¤¸à¤µà¥€ पà¥à¤°à¤¾à¤°à¥‚प"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cancel"
+msgstr "रदà¥à¤¦ करें"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Category"
+msgstr "शà¥à¤°à¥‡à¤£à¥€"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Center"
+msgstr "केनà¥à¤¦à¥à¤°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear"
+msgstr "सà¥à¤ªà¤·à¥à¤Ÿ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear SocialCalc Clipboard"
+msgstr "सà¥à¤ªà¤·à¥à¤Ÿ SocialCalc कà¥à¤²à¤¿à¤ªà¤¬à¥‹à¤°à¥à¤¡"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clipboard"
+msgstr "कà¥à¤²à¤¿à¤ªà¤¬à¥‹à¤°à¥à¤¡"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Color"
+msgstr "रंग"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Column"
+msgstr "कॉलम"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Comment"
+msgstr "टिपà¥à¤ªà¤£à¥€"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Copy"
+msgstr "पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Custom"
+msgstr "पà¥à¤°à¤¥à¤¾"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cut"
+msgstr "काटना"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default"
+msgstr "चूक"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Alignment"
+msgstr "डिफ़ॉलà¥à¤Ÿ पंकà¥à¤¤à¤¿à¤¬à¤¦à¥à¤§à¤¤à¤¾"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Column Width"
+msgstr "डिफ़ॉलà¥à¤Ÿ सà¥à¤¤à¤®à¥à¤­ चौड़ाई"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Font"
+msgstr "डिफ़ॉलà¥à¤Ÿ फ़ॉनà¥à¤Ÿ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Format"
+msgstr "डिफ़ॉलà¥à¤Ÿ सà¥à¤µà¤°à¥‚प"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Padding"
+msgstr "डिफ़ॉलà¥à¤Ÿ padding"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete"
+msgstr "मिटाना"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Column"
+msgstr "हटाà¤à¤ कॉलम"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Contents"
+msgstr "हटाà¤à¤ सामगà¥à¤°à¥€"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Row"
+msgstr "पंकà¥à¤¤à¤¿ हटाà¤à¤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Description"
+msgstr "विवरण"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Display Clipboard in"
+msgstr "पà¥à¤°à¤¦à¤°à¥à¤¶à¤¨ कà¥à¤²à¤¿à¤ªà¤¬à¥‹à¤°à¥à¤¡ में"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Down"
+msgstr "नीचे"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Edit"
+msgstr "संपादित करें"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Existing Names"
+msgstr "वरà¥à¤¤à¤®à¤¾à¤¨ नाम"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Family"
+msgstr "परिवार"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Down"
+msgstr "नीचे भरें"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Right"
+msgstr "भरने के अधिकार"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Font"
+msgstr "फ़ॉनà¥à¤Ÿ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Format"
+msgstr "पà¥à¤°à¤¾à¤°à¥‚प"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula"
+msgstr "सूतà¥à¤°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Function List"
+msgstr "समारोह की सूची"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Functions"
+msgstr "कारà¥à¤¯"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Grid"
+msgstr "गà¥à¤°à¤¿à¤¡"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hidden"
+msgstr "छिपा हà¥à¤†"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal"
+msgstr "कà¥à¤·à¥ˆà¤¤à¤¿à¤œ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Column"
+msgstr "कॉलम डालें"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Row"
+msgstr "पंकà¥à¤¤à¤¿ डा"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Italic"
+msgstr "इटैलिक"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Last Sort"
+msgstr "पिछले आधार पर छाà¤à¤Ÿà¥‡à¤‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left"
+msgstr "बायां"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left Border"
+msgstr "वाम सीमा"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link"
+msgstr "जोड़ना"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link Input Box"
+msgstr "लिंक इनपà¥à¤Ÿ बॉकà¥à¤¸"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "List"
+msgstr "सूची"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Load SocialCalc Clipboard With This"
+msgstr "लोड सोशलकेलà¥à¤• इसके साथ कà¥à¤²à¤¿à¤ªà¤¬à¥‹à¤°à¥à¤¡"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Major Sort"
+msgstr "पà¥à¤°à¤®à¥à¤– आधार पर छाà¤à¤Ÿà¥‡à¤‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Manual"
+msgstr "मैनà¥à¤…ल"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Merge Cells"
+msgstr "विलय पà¥à¤°à¤•à¥‹à¤·à¥à¤ à¥‹à¤‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Middle"
+msgstr "मधà¥à¤¯"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Minor Sort"
+msgstr "गौण आधार पर छाà¤à¤Ÿà¥‡à¤‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Insert"
+msgstr "डालें हटो"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Paste"
+msgstr "चिपकाà¤à¤ हटो"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Multi-line Input Box"
+msgstr "बहॠपंकà¥à¤¤à¤¿ इनपà¥à¤Ÿ बॉकà¥à¤¸"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Name"
+msgstr "नाम"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Names"
+msgstr "नाम"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "No padding"
+msgstr "नहीं पेढिंग"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Normal"
+msgstr "सामानà¥à¤¯"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number"
+msgstr "संखà¥à¤¯à¤¾"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number Horizontal"
+msgstr "संखà¥à¤¯à¤¾ कà¥à¤·à¥ˆà¤¤à¤¿à¤œ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "OK"
+msgstr "ठीक है"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Padding"
+msgstr " पेढिंग"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Page Name"
+msgstr "पृषà¥à¤  नाम"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste"
+msgstr "चिपकाà¤à¤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste Formats"
+msgstr "चिपकाà¤à¤ पà¥à¤°à¤¾à¤°à¥‚प"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain Text"
+msgstr "सादा पाठ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalc"
+msgstr "रिकेलà¥à¤•"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalculation"
+msgstr "रीकेलकà¥à¤²à¥‡à¤¶à¤¨"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " Redo"
+msgstr "फिर से करें"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right"
+msgstr "दायां"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right Border"
+msgstr "दाहिनी सीमा"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SHEET SETTINGS"
+msgstr "पतà¥à¤° की सà¥à¤¥à¤¾à¤ªà¤¨à¤¾"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save"
+msgstr "जमा करना"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save to"
+msgstr "बचाने के लिà¤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cell Contents"
+msgstr "निरधारित पà¥à¤°à¤•à¥‹à¤·à¥à¤  समगà¥à¤°à¥€ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Sort"
+msgstr "सेट पà¥à¤°à¤•à¥‹à¤·à¥à¤ à¥‹à¤‚ सॉरà¥à¤Ÿ करने के लिà¤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Value To"
+msgstr "निरà¥à¤§à¤¾à¤°à¤¿à¤¤ मूलà¥à¤¯"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set to Link format"
+msgstr "निरà¥à¤§à¤¾à¤°à¤¿à¤¤ पà¥à¤°à¤¾à¤°à¥‚प के लिठलिंक"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set/Clear Move From"
+msgstr "सेट / कà¥à¤²à¤¿à¤¯à¤° हटो से"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Cell Settings"
+msgstr "दिखाà¤à¤ ककà¥à¤· सेटिंगà¥à¤¸"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Sheet Settings"
+msgstr "शीटदिखाà¤à¤‚ सेटिंगà¥à¤¸"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show in new browser window"
+msgstr "नई बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤° विंडो में दिखाà¤à¤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Size"
+msgstr "आकार"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SocialCalc-save format"
+msgstr "सोशलकेलà¥à¤•-पà¥à¤°à¤¾à¤°à¥‚प को बचाने के"
+
+#msgid "Sort"
+#msgstr "कà¥à¤°à¤®à¤¬à¤¦à¥à¤§ करें"
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort"
+msgstr "कà¥à¤°à¤®à¤¬à¤¦à¥à¤§ करें"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort Cells"
+msgstr "कà¥à¤°à¤®à¤¬à¤¦à¥à¤§ करें पà¥à¤°à¤•à¥‹à¤·à¥à¤ à¥‹à¤‚ को"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Swap Colors"
+msgstr "रंगो को सà¥à¤µà¥ˆà¤ª"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Tab-delimited format"
+msgstr "टैब सीमांकित सà¥à¤µà¤°à¥‚प"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text"
+msgstr "पाठ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text Horizontal"
+msgstr "पाठ को कà¥à¤·à¥ˆà¤¤à¤¿à¤œ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "This is a<br>sample"
+msgstr "यह à¤à¤• नमूना है <बीआर>"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top"
+msgstr "चरम "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top Border"
+msgstr "शीरà¥à¤· सीमा"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "UNDONE STEPS"
+msgstr "पूरà¥à¤µà¤µà¤¤ उपाय"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "URL"
+msgstr "यूआरà¤à¤²"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Undo"
+msgstr "पूरà¥à¤µà¤µà¤¤ करें"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unmerge Cells"
+msgstr "अविलीन करें पà¥à¤°à¤•à¥‹à¤·à¥à¤ à¥‹à¤‚ को"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Up"
+msgstr "ऊपर"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Value"
+msgstr "मूलà¥à¤¯"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical"
+msgstr "खड़ा "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Workspace"
+msgstr "कारà¥à¤¯à¤•à¥à¤·à¥‡à¤¤à¥à¤°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[New]"
+msgstr "[नई]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[None]"
+msgstr "[कोई नहीं]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[select range]"
+msgstr "[चà¥à¤¨à¥‡à¤‚ सीमा]"
+
+#msgid ","
+#msgstr ","
+#msgid "."
+#msgstr "."
+#msgid "$"
+#msgstr "$"
+#msgid "["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]"
+#msgstr "["रविवार", "सोमवार", "मंगलवार", "बà¥à¤§à¤µà¤¾à¤°", "गà¥à¤°à¥à¤µà¤¾à¤°", "शà¥à¤•à¥à¤°à¤µà¤¾à¤°", "शनिवार "]"
+#msgid "["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]"
+#msgstr "["रवि", "सोम", "मंगल", "बà¥à¤§", "गà¥à¤°à¥", "शà¥à¤•à¥à¤°", "शनि "]"
+#msgid "["January", "February", "March", "April", "May", "June", "July", "August", "September",
+# "October", "November", "December"]"
+#msgstr "[ "जनवरी", "फरवरी", "मारà¥à¤š", "अपà¥à¤°à¥ˆà¤²", "मई", "जून", "जà¥à¤²à¤¾à¤ˆ", "अगसà¥à¤¤", "सितमà¥à¤¬à¤°",
+# "अकà¥à¤¤à¥‚बर", "नवमà¥à¤¬à¤°", "दिसमà¥à¤¬à¤°"]"
+#msgid "["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]"
+#msgstr "[ "जन", "फ़रवरी", "मारà¥à¤š", "अपà¥à¤°à¥ˆà¤²", "मई", "जून", "जà¥à¤²à¤¾à¤ˆ", "अगसà¥à¤¤", "सितमà¥à¤¬à¤°", "अकà¥à¤¤à¥‚बर", "नवमà¥à¤¬à¤°", "दिसमà¥à¤¬à¤°"]"
+#msgid "AM"
+#msgstr "à¤à¤à¤®"
+#msgid "A"
+#msgstr "à¤"
+#msgid "PM"
+#msgstr "पीà¤à¤®"
+#msgid "P"
+#msgstr "पी "
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed number exponent"
+msgstr "अनà¥à¤šà¤¿à¤¤ संखà¥à¤¯à¤¾ पà¥à¤°à¤¤à¤¿à¤ªà¤¾à¤¦à¤• का गठन"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unexpected character in formula"
+msgstr "सूतà¥à¤° में अनपेकà¥à¤·à¤¿à¤¤ चरितà¥à¤°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed string"
+msgstr "अनà¥à¤šà¤¿à¤¤ सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग का गठन"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed special value"
+msgstr "अनà¥à¤šà¤¿à¤¤ विशेष मूलà¥à¤¯ का गठन"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula (two operators inappropriately in a row)"
+msgstr "सूतà¥à¤° में तà¥à¤°à¥à¤Ÿà¤¿ (दो ऑपरेटरों अनà¥à¤ªà¤¯à¥à¤•à¥à¤¤ à¤à¤• पंकà¥à¤¤à¤¿ में)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing open parenthesis in list with comma(s)."
+msgstr "अलà¥à¤ªà¤µà¤¿à¤°à¤¾à¤® के साथ सूची में खà¥à¤²à¥‡ विराम गà¥à¤® ( à¤à¤¸)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Closing parenthesis without open parenthesis. "
+msgstr "खà¥à¤²à¤¾ विराम के बिना बंद कोषà¥à¤Ÿà¤•."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing close parenthesis."
+msgstr "छà¥à¤ªà¤¾ बंद कोषà¥à¤Ÿà¤•."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing operand."
+msgstr "छà¥à¤ªà¤¾ संकारà¥à¤¯"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula."
+msgstr "सूतà¥à¤° में तà¥à¤°à¥à¤Ÿà¤¿"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error value in formula"
+msgstr "सूतà¥à¤° में तà¥à¤°à¥à¤Ÿà¤¿ मूलà¥à¤¯"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula resulting in bad value"
+msgstr "सूतà¥à¤° में तà¥à¤°à¥à¤Ÿà¤¿ बà¥à¤°à¤¾ मूलà¥à¤¯ में जिसके परिणामसà¥à¤µà¤°à¥‚प"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in range value:"
+msgstr "सीमा के मूलà¥à¤¯ में फारà¥à¤®à¥‚ला परिणाम"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in an bad numeric value"
+msgstr "à¤à¤• बà¥à¤°à¤¾ संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯ में फारà¥à¤®à¥‚ला परिणाम"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Numeric overflow"
+msgstr "अंकीय अतिपà¥à¤°à¤µà¤¾à¤¹"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet unavailable:"
+msgstr "पतà¥à¤° अनà¥à¤ªà¤²à¤¬à¥à¤§:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cell reference missing when expected."
+msgstr "छà¥à¤ªà¥€ सेल संदरà¥à¤­ जब उमà¥à¤®à¥€à¤¦ थी"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet name missing when expected."
+msgstr "छà¥à¤ªà¥€ शीट नाम जब उमà¥à¤®à¥€à¤¦ थी."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Circular name reference to name"
+msgstr "परिपतà¥à¤° नाम संदरà¥à¤­ के नाम पर"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown name"
+msgstr "अजà¥à¤žà¤¾à¤¤ नाम"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Incorrect arguments to function"
+msgstr "गलत तरà¥à¤• समारोह में"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function"
+msgstr "अजà¥à¤žà¤¾à¤¤ समारोह"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LN argument must be greater than 0"
+msgstr "à¤à¤².à¤à¤¨. तरà¥à¤• को 0 से अधिक होना चाहिà¤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG10 argument must be greater than 0"
+msgstr "LOG10 तरà¥à¤• को 0 से अधिक होना चाहिà¤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG second argument must be numeric greater than 0"
+msgstr "LOG दूसरा तरà¥à¤• संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• से अधिक 0 होना चाहिà¤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG first argument must be greater than 0"
+msgstr "LOG पहली बहस 0 से अधिक होना चाहिà¤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "ROUND second argument must be numeric"
+msgstr "दूसरे दौर तरà¥à¤• संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• होना चाहिà¤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "DDB life must be greater than 1"
+msgstr "DDB जीवन 1 से अधिक होना चाहिà¤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SLN life must be greater than 1"
+msgstr "à¤à¤¸à¤à¤²à¤à¤¨ जीवन 1 से अधिक होना चाहिà¤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value"
+msgstr "मूलà¥à¤¯"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value1, value2, ..."
+msgstr "मान 1, मान 2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "valueX, valueY"
+msgstr "मूलà¥à¤¯ à¤à¤•à¥à¤¸, मूलà¥à¤¯ वाई "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "index, value1, value2, ..."
+msgstr "सूचकांक, मान 1, मान 2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range"
+msgstr "शà¥à¤°à¥‡à¤£à¥€"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, criteria"
+msgstr "शà¥à¤°à¥‡à¤£à¥€, शरà¥à¤¤à¥‡à¤‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "year, month, day"
+msgstr "वरà¥à¤·, महीने के दिन,"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "databaserange, fieldname, criteriarange"
+msgstr "डैटबेस,फ़ीलà¥à¤¡à¤¨à¥‡à¤®,कà¥à¤°à¤¾à¤à¤Ÿà¥‡à¤°à¤¿à¤¯à¤¾à¤°à¥‡à¤¨à¥à¤œ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period [, factor]"
+msgstr "लागत, बचाना, जीवन, अवधि [कारक,]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "string1, string2 [, start]"
+msgstr "1 सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग, सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग 2 [शà¥à¤°à¥‚]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [pv, [paytype]]"
+msgstr "दर, à¤à¤¨, भà¥à¤—तान, [पीवी, [पेटाईप]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, row, [rangelookup]"
+msgstr "मूलà¥à¤¯, शà¥à¤°à¥‡à¤£à¥€, पंकà¥à¤¤à¤¿, [रैनà¥à¤œà¤²à¥à¤•à¤…प]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "logical-expression, true-value, false-value"
+msgstr "तारà¥à¤•à¤¿à¤•-अभिवà¥à¤¯à¤•à¥à¤¤à¤¿, सही मूलà¥à¤¯, à¤à¥‚ठी मूलà¥à¤¯"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, rownum, colnum"
+msgstr "शà¥à¤°à¥‡à¤£à¥€, पंकà¥à¤¤à¤¿ संखà¥à¤¯à¤¾, सà¥à¤¤à¤‚भ संखà¥à¤¯à¤¾"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, [guess]"
+msgstr "सीमा, [अनà¥à¤®à¤¾à¤¨]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, count"
+msgstr "पाठ, गिनती"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, base"
+msgstr "मूलà¥à¤¯ , आधार"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, [rangelookup]"
+msgstr "मूलà¥à¤¯, शà¥à¤°à¥‡à¤£à¥€, [रैनà¥à¤œà¤²à¥à¤•à¤…प]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, start, length"
+msgstr "पाठ, पà¥à¤°à¤¾à¤°à¤‚भ, लंबाई"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, payment, pv, [fv, [paytype]]"
+msgstr "दर, भà¥à¤—तान, पीवी , [à¤à¥žà¤µà¥€ , [ पेटाईप ]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, value1, value2, ..."
+msgstr "दर, मान 1, मान 2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, pv, [fv, [paytype]]"
+msgstr "दर,रैनà¥à¤œà¤²à¥à¤•à¤…प , पीवी , [à¤à¥žà¤µà¥€ , [ पेटाईप ]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [fv, [paytype]]"
+msgstr "दर, à¤à¤¨, भà¥à¤—तान, [à¤à¥žà¤µà¥€ , [ पेटाईप ]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "n, payment, pv, [fv, [paytype, [guess]]]"
+msgstr "à¤à¤¨, भà¥à¤—तान, पीवी, [à¤à¥žà¤µà¥€, [पेटाईप, [अनà¥à¤®à¤¾à¤¨]]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, start, length, text2"
+msgstr "1 पाठ, पà¥à¤°à¤¾à¤°à¤‚भ, लंबाई, 2 पाठ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, [precision]"
+msgstr "मूलà¥à¤¯, [सटीक]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime"
+msgstr "लागत, बचाना, जीवन"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period"
+msgstr "लागत, बचाना, जीवन, अवध"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, oldtext, newtext [, occurrence]"
+msgstr "1 पाठ, पà¥à¤°à¤¾à¤¨à¥‡ पाठ, नया पाठ [घटना,]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range1, criteria [, range2]"
+msgstr "शà¥à¤°à¥‡à¤£à¥€ 1, मापदंड [, सीमा 2]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "hour, minute, second"
+msgstr "घंटा, मिनट, पल"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text"
+msgstr "पाठ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, col, [rangelookup]"
+msgstr "मूलà¥à¤¯, शà¥à¤°à¥‡à¤£à¥€, करà¥à¤¨à¤², [रैनà¥à¤œà¤²à¥à¤•à¤…प]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date, [type]"
+msgstr "तारीख, [पà¥à¤°à¤•à¤¾à¤°]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date"
+msgstr "तारीख "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "All"
+msgstr "सभी"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Statistics"
+msgstr "सांखà¥à¤¯à¤¿à¤•à¥€ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Lookup"
+msgstr "लà¥à¤•à¤…प"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Financial"
+msgstr "वितà¥à¤¤à¥€à¤¯"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Test"
+msgstr "टेसà¥à¤Ÿ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Math"
+msgstr "गणित"
+
+#msgid "Text"
+#msgstr "पाठ"
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Not Set"
+msgstr "सेट नहीं"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "Cells to Graph"
+#msgstr "सेल गà¥à¤°à¤¾à¤«à¤¼ को "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Graph"
+msgstr "सेट सेल करने के लिठगà¥à¤°à¤¾à¤«à¤¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph Type"
+msgstr "गà¥à¤°à¤¾à¤«à¤¼ पà¥à¤°à¤•à¤¾à¤°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "filter:alpha(opacity=90);opacity:.9;"
+msgstr "फिलà¥à¤Ÿà¤°: अलà¥à¤«à¤¾ (= 90 असà¥à¤ªà¤·à¥à¤Ÿà¤¤à¤¾); अपारदरà¥à¤¶à¤¿à¤¤à¤¾: .9;"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Absolute value function. "
+msgstr "निरपेकà¥à¤· मूलà¥à¤¯ कà¥à¤°à¤¿à¤¯à¤¾."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arccosine function. "
+msgstr "तà¥à¤°à¤¿à¤•à¥‹à¤£à¤®à¤¿à¤¤à¥€à¤¯ अरà¥à¤•à¤•à¥‹à¤¸à¤¾à¤‡à¤¨ कà¥à¤°à¤¿à¤¯à¤¾. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if all arguments are true. "
+msgstr "अगर यह सही है सभी तरà¥à¤• सही हैं. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arcsine function. "
+msgstr "तà¥à¤°à¤¿à¤•à¥‹à¤£à¤®à¤¿à¤¤à¥€à¤¯ अरà¥à¤•à¤•à¥‹à¤¸à¤¾à¤‡à¤¨ कà¥à¤°à¤¿à¤¯à¤¾. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arctan function. "
+msgstr "तà¥à¤°à¤¿à¤•à¥‹à¤£à¤®à¤¿à¤¤à¥€à¤¯ अरà¥à¤•à¤Ÿà¥ˆà¤¨ कà¥à¤°à¤¿à¤¯à¤¾. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arc tangent function (result is in radians). "
+msgstr "परिणाम तà¥à¤°à¤¿à¤•à¥‹à¤£à¤®à¤¿à¤¤à¥€à¤¯ आरà¥à¤•à¤¸à¥à¤ªà¤°à¥à¤¶à¤œà¥à¤¯à¤¾ कà¥à¤°à¤¿à¤¯à¤¾ (रैडीयन में है). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values. "
+msgstr "औसत मूलà¥à¤¯ हैं. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value specified by the index. The values may be ranges of cells. "
+msgstr "रिटरà¥à¤¨ सूचकांक दà¥à¤µà¤¾à¤°à¤¾ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ मूलà¥à¤¯. मूलà¥à¤¯à¥‹à¤‚ कोशिकाओं की शà¥à¤°à¥ƒà¤‚खला हो सकती है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of columns in the range. "
+msgstr "रिटरà¥à¤¨ रेंज में कॉलम की संखà¥à¤¯à¤¾. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric cosine function (value is in radians). "
+msgstr "तà¥à¤°à¤¿à¤•à¥‹à¤£à¤®à¤¿à¤¤à¥€à¤¯ कोसाइन समारोह (मूलà¥à¤¯ रैडीयन में है)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error. "
+msgstr "संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯à¥‹à¤‚ की संखà¥à¤¯à¤¾, रिकà¥à¤¤ नहीं, पाठ, या तà¥à¤°à¥à¤Ÿà¤¿ मायने रखता है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values. "
+msgstr "गैर की संखà¥à¤¯à¤¾ में रिकà¥à¤¤ मूलà¥à¤¯à¥‹à¤‚ मायने रखता है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of blank values. (Note: '' is not blank.) "
+msgstr "कोरा मूलà¥à¤¯à¥‹à¤‚ की संखà¥à¤¯à¤¾ में गिना जाता है. (नोट: '' खाली नहीं है.)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of number of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). "
+msgstr "रेंज में कोशिकाओं की संखà¥à¤¯à¤¾ की संखà¥à¤¯à¤¾ मानदंडों को पूरा: मायने रखता है. मानदंड à¤à¤• मान हो सकता है ( à¤à¤•à¥à¤¸, 15, 1 3) या à¤à¤• परीकà¥à¤·à¤¾ (> 25). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the appropriate date value given numbers for year, month, and day. For example: DATE(2006,2,1) for February 1, 2006. Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "रिटरà¥à¤¨ उपयà¥à¤•à¥à¤¤ तारीख वरà¥à¤· के लिठनंबर, महीने के मूलà¥à¤¯ दिया, और दिन. उदाहरण के लिठDATE 2006,2,1 (:) 1 फ़रवरी 2006 के लिà¤. नोट: इस कारà¥à¤¯à¤•à¥à¤°à¤® में, 1 दिन 31 दिसमà¥à¤¬à¤° 1899 और 1900 साल है à¤à¤• छलांग वरà¥à¤· नहीं है. कà¥à¤› कारà¥à¤¯à¤•à¥à¤°à¤®à¥‹à¤‚ को 1 जनवरी 1900 का उपयोग करें, दिन के रूप में 1 और à¤à¤• छलांग के रूप में वरà¥à¤· 1900 का इलाज. दोनों ही मामलों में, हालाà¤à¤•à¤¿, पर या 1 मारà¥à¤š 1900 के बाद की तारीख, वही कर रहे हैं. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values in the specified field in records that meet the criteria. "
+msgstr "औसत निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कà¥à¤·à¥‡à¤¤à¥à¤° में रिकॉरà¥à¤¡ में मूलà¥à¤¯à¥‹à¤‚ मानदंडों को पूरा. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of month for a date value. "
+msgstr "à¤à¤• तारीख मूलà¥à¤¯ के लिठरिटरà¥à¤¨ महीने के दिन. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error, in the specified field in records that meet the criteria. "
+msgstr "संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯à¥‹à¤‚ की संखà¥à¤¯à¤¾, रिकà¥à¤¤ नहीं, पाठ, या निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कà¥à¤·à¥‡à¤¤à¥à¤° में तà¥à¤°à¥à¤Ÿà¤¿, रिकॉरà¥à¤¡ में है कि मानदंडों को पूरा मायने रखता है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values in the specified field in records that meet the criteria. "
+msgstr "गैर की संखà¥à¤¯à¤¾ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कà¥à¤·à¥‡à¤¤à¥à¤° में रिकà¥à¤¤ मूलà¥à¤¯à¥‹à¤‚ रिकॉरà¥à¤¡ में है कि मानदंडों को पूरा मायने रखता है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at the given period of time (the default factor is 2 for double-declining balance). "
+msgstr "समय दिया अवधि में रिटरà¥à¤¨ मूलà¥à¤¯à¤¹à¥à¤°à¤¾à¤¸ की राशि (डिफ़ॉलà¥à¤Ÿ कारक डबल गिरावट के शेष के लिठ2 है). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in radians into degrees. "
+msgstr "डिगà¥à¤°à¥€ में रैडीयन मूलà¥à¤¯ में धरà¥à¤®à¤¾à¤¨à¥à¤¤à¤°à¤¿à¤¤. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value of the specified field in the single record that meets the criteria. "
+msgstr "रिटरà¥à¤¨ à¤à¤• रिकारà¥à¤¡ है कि मानदंड बैठक में निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कà¥à¤·à¥‡à¤¤à¥à¤° के महतà¥à¤µ होता है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "लाभ के रिकॉरà¥à¤¡ में निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कà¥à¤·à¥‡à¤¤à¥à¤° में संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯à¥‹à¤‚ की अधिकतम कि मानदंडों को पूरा. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "Returns the maximum of the numeric values in the specified field in records that meet the criteria. "
+#msgstr "लाभ के रिकॉरà¥à¤¡ में निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कà¥à¤·à¥‡à¤¤à¥à¤° में संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯à¥‹à¤‚ की अधिकतम कि मानदंडों को पूरा. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values in the specified field in records that meet the criteria. "
+msgstr "लाभ के रिकॉरà¥à¤¡ में निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कà¥à¤·à¥‡à¤¤à¥à¤° में संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯ बढ़ रही है कि मानदंडों को पूरा का नतीजा है."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "रिटरà¥à¤¨ रिकॉरà¥à¤¡ में निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कà¥à¤·à¥‡à¤¤à¥à¤° में संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯à¥‹à¤‚ का नमूना मानक विचलन है कि मानदंडों को पूरा. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "लाभ के रिकॉरà¥à¤¡ में निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कà¥à¤·à¥‡à¤¤à¥à¤° में संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯à¥‹à¤‚ का मानक विचलन है कि मानदंडों को पूरा. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "अभिलेखों में निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कà¥à¤·à¥‡à¤¤à¥à¤° में संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯à¥‹à¤‚ की राशि रिटरà¥à¤¨ कि मानदंडों को पूरा. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "लाभ के रिकॉरà¥à¤¡ में निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कà¥à¤·à¥‡à¤¤à¥à¤° में संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯à¥‹à¤‚ के नमूने विचरण कि मानदंडों को पूरा. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "लाभ के रिकॉरà¥à¤¡ में निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कà¥à¤·à¥‡à¤¤à¥à¤° में संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯à¥‹à¤‚ के विचलन कि मानदंडों को पूरा. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest even integer. "
+msgstr "दौर की सबसे पास के परिमाण में उठ मूलà¥à¤¯ भी पूरà¥à¤£à¤¾à¤‚क"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the values are exactly the same, including case, type, etc. "
+msgstr "रिटरà¥à¤¨ सही अगर मूलà¥à¤¯à¥‹à¤‚ बिलà¥à¤•à¥à¤² मामला है, उसी पà¥à¤°à¤•à¤¾à¤° सहित, आदि कर रहे हैं"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns e raised to the value power. "
+msgstr "रिटरà¥à¤¨ ई मूलà¥à¤¯ सतà¥à¤¤à¤¾ में उठाया. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns factorial of the value. "
+msgstr "मूलà¥à¤¯ के कारख़ाने लौट आया. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value false. "
+msgstr "रिटरà¥à¤¨ तारà¥à¤•à¤¿à¤• मान à¤à¥‚ठे "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the starting position within string2 of the first occurrence of string1 at or after start. If start is omitted, 1 is assumed. "
+msgstr "रिटरà¥à¤¨ सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग के भीतर का मूलà¥à¤¯ उस सà¥à¤¥à¤¿à¤¤à¤¿ सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग की पहली घटना के 2-पर 1 या शà¥à¤°à¥à¤†à¤¤ के बाद. अगर शà¥à¤°à¥‚ लोप है, 1 माना जाता है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the future value of repeated payments of money invested at the given rate for the specified number of periods, with optional present value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "समय की निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ संखà¥à¤¯à¤¾ के लिठदी दर पर पैसा निवेश की पà¥à¤¨à¤°à¤¾à¤µà¥ƒà¤¤à¥à¤¤à¤¿ भà¥à¤—तान के भविषà¥à¤¯ के मूलà¥à¤¯ रिटरà¥à¤¨, वैकलà¥à¤ªà¤¿à¤• वरà¥à¤¤à¤®à¤¾à¤¨ मूलà¥à¤¯ (0 डिफ़ॉलà¥à¤Ÿ) और भà¥à¤—तान पà¥à¤°à¤•à¤¾à¤° के साथ (0 डिफ़ॉलà¥à¤Ÿ = अवधि के अंत में, 1 अवधि की शà¥à¤°à¥à¤†à¤¤ =). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the row offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. "
+msgstr "शà¥à¤°à¥‡à¤£à¥€ में दी मूलà¥à¤¯ के लिठमिलान मूलà¥à¤¯ के लिठदेखो और मà¥à¤¦à¥à¤°à¤£ पंकà¥à¤¤à¤¿ दà¥à¤µà¤¾à¤°à¤¾ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ सेल में इसी मूलà¥à¤¯ वापसी. यदि रेनà¥à¤œà¤²à¥à¤•à¤…प 1 (डिफ़ॉलà¥à¤Ÿ) और नहीं 0, अगर नà¥à¤¯à¥‚मेरिक कोषà¥à¤ à¤• के भीतर मैच है (मैच <मूलà¥à¤¯ =) के बजाय सटीक मेल का. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the hour portion of a time or date/time value. "
+msgstr "रिटरà¥à¤¨ à¤à¤• समय या तिथि के घंटे भाग / समय मान. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Results in true-value if logical-expression is TRUE or non-zero, otherwise results in false-value. "
+msgstr "सच मूलà¥à¤¯ में: परिणाम अगर तारà¥à¤•à¤¿à¤•-अभिवà¥à¤¯à¤•à¥à¤¤à¤¿ सही है या गैर शूनà¥à¤¯, नहीं तो à¤à¥‚ठी मूलà¥à¤¯ में परिणाम है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns a cell or range reference for the specified row and column in the range. If range is 1-dimensional, then only one of rownum or colnum are needed. If range is 2-dimensional and rownum or colnum are zero, a reference to the range of just the specified column or row is returned. You can use the returned reference value in a range, e.g., sum(A1:INDEX(A2:A10,4)). "
+msgstr "रिटरà¥à¤¨ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ पंकà¥à¤¤à¤¿ और सà¥à¤¤à¤‚भ के लिठà¤à¤• सेल या शà¥à¤°à¥‡à¤£à¥€ शà¥à¤°à¥‡à¤£à¥€ संदरà¥à¤­ में. यदि सीमा 1-आयामी है, तो केवल रोनम या कोलनम में से à¤à¤• है की जरूरत है. यदि सीमा 2-आयामी और रोनम या कोलनम है शूनà¥à¤¯ हैं, बस निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ सà¥à¤¤à¤‚भ या पंकà¥à¤¤à¤¿ की दूरी के लिठà¤à¤• संदरà¥à¤­ लौटा है. तà¥à¤® à¤à¤• रेंज में वापस संदरà¥à¤­ मूलà¥à¤¯ उपयोग करते हैं, जैसे, (ठ1: राशि (ठ2: ठ10,4)) सूचकांक में वृदà¥à¤§à¤¿ कर सकते हैं. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value rounded down to the nearest integer (towards -infinity). "
+msgstr "रिटरà¥à¤¨ मूलà¥à¤¯ निकटतम पूरà¥à¤£à¤¾à¤‚क के लिठनीचे गोल (पà¥à¤°à¤¤à¤¿ अनंत). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the interest rate at which the cash flows in the range have a net present value of zero. Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "लाभ बà¥à¤¯à¤¾à¤œ दर पर जो नकद सीमा में बहती है शूनà¥à¤¯ का शà¥à¤¦à¥à¤§ वरà¥à¤¤à¤®à¤¾à¤¨ मूलà¥à¤¯ है. à¤à¤• चलने पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ # नम लौटेगा का उपयोग करता है! तà¥à¤°à¥à¤Ÿà¤¿ à¤à¤•à¤¾à¤—à¥à¤° नहीं अगर यह होता है. वहाठà¤à¤• से अधिक संभव समाधान हो सकता है. वैकलà¥à¤ªà¤¿à¤• मूलà¥à¤¯ लगता है कà¥à¤› सà¥à¤¥à¤¿à¤¤à¤¿à¤¯à¥‹à¤‚ में, जहां यह नहीं à¤à¤•à¤¾à¤—à¥à¤° मदद मिल सकती है या अनà¥à¤šà¤¿à¤¤ समाधान उपलबà¥à¤§ कराना पाता है (डिफ़ॉलà¥à¤Ÿ लगता है कि 10% है). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is a reference to a blank cell. "
+msgstr "रिटरà¥à¤¨ सही अगर मूलà¥à¤¯ à¤à¤• खाली पà¥à¤°à¤•à¥‹à¤·à¥à¤  के लिठà¤à¤• संदरà¥à¤­ है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error but not NA. "
+msgstr "रिटरà¥à¤¨ सही अगर मान पà¥à¤°à¤•à¤¾à¤° की है तà¥à¤°à¥à¤Ÿà¤¿ नहीं à¤à¤¨à¤."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error. "
+msgstr "रिटरà¥à¤¨ सही अगर मान पà¥à¤°à¤•à¤¾à¤° की है तà¥à¤°à¥à¤Ÿà¤¿. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Logical (true/false). "
+msgstr "रिटरà¥à¤¨ सही अगर मान पà¥à¤°à¤•à¤¾à¤° की है लॉजिकल (सही / गलत)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is the error type NA. "
+msgstr "रिटरà¥à¤¨ सही अगर मूलà¥à¤¯ तà¥à¤°à¥à¤Ÿà¤¿ पà¥à¤°à¤•à¤¾à¤° à¤à¤¨à¤ है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is not of type Text. "
+msgstr "रिटरà¥à¤¨ सही अगर मान पà¥à¤°à¤•à¤¾à¤° का नहीं है पाठ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Number (including logical values). "
+msgstr "रिटरà¥à¤¨ सही अगर मूलà¥à¤¯ संखà¥à¤¯à¤¾ (तारà¥à¤•à¤¿à¤• मान सहित पà¥à¤°à¤•à¤¾à¤° का है)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Text. "
+msgstr "रिटरà¥à¤¨ सही अगर मान पà¥à¤°à¤•à¤¾à¤° की है पाठ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value. If count is omitted, 1 is assumed. "
+msgstr "रिटरà¥à¤¨ अकà¥à¤·à¤° का पाठ मूलà¥à¤¯ से निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ संखà¥à¤¯à¤¾. यदि गणना लोप है, 1 माना जाता है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of characters in the text value. "
+msgstr "रिटरà¥à¤¨ पाठ मूलà¥à¤¯ में पातà¥à¤°à¥‹à¤‚ की संखà¥à¤¯à¤¾. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the natural logarithm of the value. "
+msgstr "रिटरà¥à¤¨ मूलà¥à¤¯ का पà¥à¤°à¤¾à¤•à¥ƒà¤¤à¤¿à¤• लघà¥à¤—णक. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logarithm of the value using the specified base. "
+msgstr "रिटरà¥à¤¨ मूलà¥à¤¯ का लघà¥à¤—णक निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ आधार का उपयोग कर. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the base 10 logarithm of the value. "
+msgstr "लाभ के आधार मूलà¥à¤¯ का 10 लघà¥à¤—णक. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all uppercase characters converted to lowercase. "
+msgstr "रिटरà¥à¤¨ सभी अपरकेस में परिवरà¥à¤¤à¤¿à¤¤ लोअरकेस वरà¥à¤£à¥‹à¤‚ के साथ पाठ मान. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return position (the first is 1) in that range. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. If rangelookup is -1, act like 1 but the bracket is match>=value. "
+msgstr "शà¥à¤°à¥‡à¤£à¥€ में दी मूलà¥à¤¯ और लाभ की सà¥à¤¥à¤¿à¤¤à¤¿ के लिठमिलान मूलà¥à¤¯ के लिठदेखो (1 पहले है) कि सीमा में. यदि रेनà¥à¤œà¤²à¥à¤•à¤…प 1 (डिफ़ॉलà¥à¤Ÿ) और नहीं 0, अगर नà¥à¤¯à¥‚मेरिक कोषà¥à¤ à¤• के भीतर मैच है (मैच <मूलà¥à¤¯ =) के बजाय सटीक मेल का. यदि रेनà¥à¤œà¤²à¥à¤•à¤…प -1, 1 की तरह अभिनय लेकिन वरà¥à¤— मैच> है मूलà¥à¤¯ = है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values. "
+msgstr "रिटरà¥à¤¨ संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯à¥‹à¤‚ की अधिकतम. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the specified position. "
+msgstr "लाभ पातà¥à¤°à¥‹à¤‚ का मूल पाठ इस पà¥à¤°à¤•à¤¾à¤° निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ सà¥à¤¥à¤¾à¤¨ से शà¥à¤°à¥‚ मूलà¥à¤¯ से निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ संखà¥à¤¯à¤¾. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minimum of the numeric values. "
+msgstr "रिटरà¥à¤¨ संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯à¥‹à¤‚ के कम से कम. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minute portion of a time or date/time value. "
+msgstr "रिटरà¥à¤¨ à¤à¤• समय या तिथि के मिनट भाग / समय मान. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the remainder of the first value divided by the second. "
+msgstr "रिटरà¥à¤¨ पहले दूसरे से विभाजित मूलà¥à¤¯ का शेष. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the month part of a date value. "
+msgstr "वापसी की तारीख à¤à¤• महीने के मूलà¥à¤¯ का हिसà¥à¤¸à¤¾ है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value if it is a numeric value otherwise an error. "
+msgstr "रिटरà¥à¤¨ मूलà¥à¤¯ अगर यह à¤à¤• अंकीय मान अनà¥à¤¯à¤¥à¤¾ à¤à¤• तà¥à¤°à¥à¤Ÿà¤¿ है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the #N/A error value which propagates through most operations. "
+msgstr "रिटरà¥à¤¨ # à¤à¤¨ / ठतà¥à¤°à¥à¤Ÿà¤¿ मान है जो सबसे जà¥à¤¯à¤¾à¤¦à¤¾ अभियानों के माधà¥à¤¯à¤® से propagates. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns FALSE if value is true, and TRUE if it is false. "
+msgstr "कापरिणामहोगागलत अगर मूलà¥à¤¯ सही है, और अगर यह à¤à¥‚ठा सच है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date/time. "
+msgstr "रिटरà¥à¤¨ वरà¥à¤¤à¤®à¤¾à¤¨ दिनांक / समय."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of periods at which payments invested each period at the given rate with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period) has the given present value. "
+msgstr "रिटरà¥à¤¨ जो समय पर भà¥à¤—तान वैकलà¥à¤ªà¤¿à¤• भविषà¥à¤¯ मूलà¥à¤¯ (0 डिफ़ॉलà¥à¤Ÿ) और भà¥à¤—तान पà¥à¤°à¤•à¤¾à¤° के साथ दिया दर से पà¥à¤°à¤¤à¥à¤¯à¥‡à¤• अवधि के निवेश (0 डिफ़ॉलà¥à¤Ÿ = अवधि के अंत में, 1 अवधि की शà¥à¤°à¥à¤†à¤¤ =) की संखà¥à¤¯à¤¾ दी वरà¥à¤¤à¤®à¤¾à¤¨ मूलà¥à¤¯ है."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the net present value of cash flows (which may be individual values and/or ranges) at the given rate. The flows are positive if income, negative if paid out, and are assumed at the end of each period. "
+msgstr "रिटरà¥à¤¨ नकदी पà¥à¤°à¤µà¤¾à¤¹ का शà¥à¤¦à¥à¤§ वरà¥à¤¤à¤®à¤¾à¤¨ मूलà¥à¤¯ (जो वà¥à¤¯à¤•à¥à¤¤à¤¿à¤—त मूलà¥à¤¯à¥‹à¤‚ और सीमाओं या / दिया दर पर) हो सकता है. पà¥à¤°à¤µà¤¾à¤¹ सकारातà¥à¤®à¤• अगर आय, अगर बाहर भà¥à¤—तान नकारातà¥à¤®à¤• हैं, और पà¥à¤°à¤¤à¥à¤¯à¥‡à¤• अवधि के अंत में गà¥à¤°à¤¹à¤£ कर रहे हैं. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest odd integer. "
+msgstr "दौर निकटतम विषम पूरà¥à¤£à¤¾à¤‚क के परिमाण में उठ मूलà¥à¤¯. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if any argument is true "
+msgstr "यह सच है कि किसी भी तरà¥à¤• सच है, "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "The value 3.1415926... "
+msgstr "3.1415926 मूलà¥à¤¯ ... "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of each payment that must be invested at the given rate for the specified number of periods to have the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "रिटरà¥à¤¨ पà¥à¤°à¤¤à¥à¤¯à¥‡à¤• भà¥à¤—तान के उस समय के निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ संखà¥à¤¯à¤¾ के लिठदी दर पर निवेश किया जाना चाहिठनिरà¥à¤¦à¤¿à¤·à¥à¤Ÿ वरà¥à¤¤à¤®à¤¾à¤¨ मूलà¥à¤¯ है, वैकलà¥à¤ªà¤¿à¤• भविषà¥à¤¯ मूलà¥à¤¯ (0 डिफ़ॉलà¥à¤Ÿ) और भà¥à¤—तान पà¥à¤°à¤•à¤¾à¤° के साथ (0 डिफ़ॉलà¥à¤Ÿ = अवधि के अंत में, 1 = की राशि अवधि की शà¥à¤°à¥à¤†à¤¤). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the first value raised to the second value power. "
+msgstr "रिटरà¥à¤¨ पहली मूलà¥à¤¯ दूसरी मूलà¥à¤¯ सतà¥à¤¤à¤¾ में उठाया. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values. "
+msgstr "रिटरà¥à¤¨ संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯ बढ़ का नतीजा है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with the first letter of each word converted to uppercase and the others to lowercase. "
+msgstr "लाभ के लिठपà¥à¤°à¤¤à¥à¤¯à¥‡à¤• अपरकेस और दूसरों को लोअरकेस में परिवरà¥à¤¤à¤¿à¤¤ शबà¥à¤¦ के पहले अकà¥à¤·à¤° से पाठ मान. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the present value of the given number of payments each invested at the given rate, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "लाभ के भà¥à¤—तान की दी गई संखà¥à¤¯à¤¾ के वरà¥à¤¤à¤®à¤¾à¤¨ मूलà¥à¤¯ दी दर पर निवेश किया, वैकलà¥à¤ªà¤¿à¤• भविषà¥à¤¯ मूलà¥à¤¯ (0 डिफ़ॉलà¥à¤Ÿ) और भà¥à¤—तान पà¥à¤°à¤•à¤¾à¤° के साथ (0 डिफ़ॉलà¥à¤Ÿ = अवधि के अंत में, 1 अवधि की शà¥à¤°à¥à¤†à¤¤ = पà¥à¤°à¤¤à¥à¤¯à¥‡à¤•). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in degrees into radians. "
+msgstr "डिगà¥à¤°à¥€ में कांति मूलà¥à¤¯ में धरà¥à¤®à¤¾à¤¨à¥à¤¤à¤°à¤¿à¤¤. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the rate at which the given number of payments each invested at the given rate has the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "रिटरà¥à¤¨ दर जिस पर भà¥à¤—तान की दी गई संखà¥à¤¯à¤¾ पà¥à¤°à¤¤à¥à¤¯à¥‡à¤• दी दर पर निवेश निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ वरà¥à¤¤à¤®à¤¾à¤¨ मूलà¥à¤¯ है, वैकलà¥à¤ªà¤¿à¤• भविषà¥à¤¯ मूलà¥à¤¯ (0 डिफ़ॉलà¥à¤Ÿ) और भà¥à¤—तान पà¥à¤°à¤•à¤¾à¤° के साथ (= अवधि के अंत में डिफ़ॉलà¥à¤Ÿ 0, 1 = अवधि की शà¥à¤°à¥à¤†à¤¤). चलने का à¤à¤• पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ है कि # नम लौटेगा का उपयोग करता है! तà¥à¤°à¥à¤Ÿà¤¿ à¤à¤•à¤¾à¤—à¥à¤° नहीं अगर यह होता है. वहाठà¤à¤• से अधिक संभव समाधान हो सकता है. वैकलà¥à¤ªà¤¿à¤• मूलà¥à¤¯ लगता है कà¥à¤› सà¥à¤¥à¤¿à¤¤à¤¿à¤¯à¥‹à¤‚ में, जहां यह नहीं à¤à¤•à¤¾à¤—à¥à¤° मदद मिल सकती है या अनà¥à¤šà¤¿à¤¤ समाधान उपलबà¥à¤§ कराना पाता है (डिफ़ॉलà¥à¤Ÿ लगता है कि 10% है). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the specified number of characters starting from the specified position replaced by text2. "
+msgstr "रिटरà¥à¤¨ पाठ-1 निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ पाठ की जगह की सà¥à¤¥à¤¿à¤¤à¤¿-2 का मूलà¥à¤¯ उस अकà¥à¤·à¤° के निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ संखà¥à¤¯à¤¾ के साथ. "
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text repeated the specified number of times. "
+msgstr "रिटरà¥à¤¨ पाठ बार की निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ संखà¥à¤¯à¤¾ दोहराया. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the end. If count is omitted, 1 is assumed. "
+msgstr "लाभ पातà¥à¤°à¥‹à¤‚ की निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ पाठ के अंत से शà¥à¤°à¥‚ मूलà¥à¤¯ से संखà¥à¤¯à¤¾. यदि गणना लोप है, 1 माना जाता है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value to the specified number of decimal places. If precision is negative, then round to powers of 10. The default precision is 0 (round to integer). "
+msgstr "दौर दशमलव सà¥à¤¥à¤¾à¤¨à¥‹à¤‚ की निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ संखà¥à¤¯à¤¾ के लिठमान. यदि सटीक नकारातà¥à¤®à¤• है, तो दौर 10 की शकà¥à¤¤à¤¿à¤¯à¥‹à¤‚ को. डिफ़ॉलà¥à¤Ÿ सटीक 0 दौर (को पूरà¥à¤£à¤¾à¤‚क) है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of rows in the range. "
+msgstr "रिटरà¥à¤¨ रेंज में पंकà¥à¤¤à¤¿à¤¯à¥‹à¤‚ की संखà¥à¤¯à¤¾. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the second portion of a time or date/time value (truncated to an integer). "
+msgstr "रिटरà¥à¤¨ à¤à¤• समय या तिथि के दूसरे भाग / समय (मूलà¥à¤¯ à¤à¤• पूरà¥à¤£à¤¾à¤‚क तक छोटा कर दिया). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric sine function (value is in radians) "
+msgstr "तà¥à¤°à¤¿à¤•à¥‹à¤£à¤®à¤¿à¤¤à¥€à¤¯ साइन समारोह (मूलà¥à¤¯ कांति में है )"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at each period of time using the straight-line method. "
+msgstr "समय के पà¥à¤°à¤¤à¥à¤¯à¥‡à¤• अवधि के-सीधी रेखा पदà¥à¤§à¤¤à¤¿ का उपयोग करके पर रिटरà¥à¤¨ मूलà¥à¤¯à¤¹à¥à¤°à¤¾à¤¸ की राशि. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Square root of the value "
+msgstr " मूलà¥à¤¯ का वरà¥à¤—मूल"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values. "
+msgstr "रिटरà¥à¤¨ नमूना संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯à¥‹à¤‚ का मानक विचलन. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values. "
+msgstr "रिटरà¥à¤¨ संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯à¥‹à¤‚ का मानक विचलन. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the all occurrences of oldtext replaced by newtext. If occurrence is present, then only that occurrence is replaced. "
+msgstr "रिटरà¥à¤¨ पाठ-1 निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ पाठ की जगह की सà¥à¤¥à¤¿à¤¤à¤¿-2 का मूलà¥à¤¯ उस अकà¥à¤·à¤° के निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ संखà¥à¤¯à¤¾ के साथ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Adds the numeric values. The values to the sum function may be ranges in the form similar to A1:B5. "
+msgstr "संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मान जोड़ता है. राशि समारोह में मूलà¥à¤¯à¥‹à¤‚ ठ1 के समान रूप: ठ5 में परà¥à¤µà¤¤à¤®à¤¾à¤²à¤¾ हो सकता है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sums the numeric values of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). If range2 is present, then range1 is tested and the corresponding range2 value is summed. "
+msgstr "शà¥à¤°à¥‡à¤£à¥€ में कोशिकाओं का संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯ राशियाठकि मानदंडों को पूरा. मानदंड à¤à¤• मान हो सकता है ( à¤à¤•à¥à¤¸, 15, 1 3) या à¤à¤• परीकà¥à¤·à¤¾ (> 25). यदि सीमा 2 मौजूद है, तो range1 और परीकà¥à¤·à¤£ इसी सीमा 2 मूलà¥à¤¯ अभिवà¥à¤¯à¤•à¥à¤¤ किया है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Depreciation by Sum of Year's Digits method. "
+msgstr "वरà¥à¤· के जोड़ से मूलà¥à¤¯à¤¹à¥à¤°à¤¾à¤¸ अंक विधि à¤à¤¸. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value or else a null string. "
+msgstr "रिटरà¥à¤¨ पाठ या किसी और मूलà¥à¤¯ à¤à¤• रिकà¥à¤¤ सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric tangent function (value is in radians) "
+msgstr "मूलà¥à¤¯ तà¥à¤°à¤¿à¤•à¥‹à¤£à¤®à¤¿à¤¤à¥€à¤¯ सà¥à¤ªà¤°à¥à¤¶à¤°à¥‡à¤–ा समारोह (कांति में है)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the time value given the specified hour, minute, and second. "
+msgstr "रिटरà¥à¤¨ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ घंटा, मिनट, और दूसरी बार मूलà¥à¤¯ दिया."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with leading, trailing, and repeated spaces removed. "
+msgstr "रिटरà¥à¤¨ आज की तारीख (à¤à¤• पूरà¥à¤£à¤¾à¤‚क). नोट: इस कारà¥à¤¯à¤•à¥à¤°à¤® में, 1 दिन 31 दिसमà¥à¤¬à¤° 1899 और 1900 साल है à¤à¤• छलांग वरà¥à¤· नहीं है. कà¥à¤› कारà¥à¤¯à¤•à¥à¤°à¤®à¥‹à¤‚ को 1 जनवरी 1900 का उपयोग करें, दिन के रूप में 1 और à¤à¤• छलांग के रूप में वरà¥à¤· 1900 का इलाज. दोनों ही मामलों में, हालाà¤à¤•à¤¿, पर या 1 मारà¥à¤š 1900 के बाद की तारीख, वही क"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value true. "
+msgstr "पà¥à¤°à¤®à¥à¤– के साथ पाठ मूलà¥à¤¯ रिटरà¥à¤¨, पीछे, और दोहराया रिकà¥à¤¤ सà¥à¤¥à¤¾à¤¨ हटा दिया. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Truncates the value to the specified number of decimal places. If precision is negative, truncate to powers of 10. "
+msgstr "काटना दशमलव सà¥à¤¥à¤¾à¤¨à¥‹à¤‚ की निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ संखà¥à¤¯à¤¾ के लिठमान. यदि सटीक नकारातà¥à¤®à¤• है, 10 की शकà¥à¤¤à¤¿à¤¯à¥‹à¤‚ को काटना"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all lowercase characters converted to uppercase. "
+msgstr "लाभ सभी लोअरकेस में परिवरà¥à¤¤à¤¿à¤¤ अपरकेस अकà¥à¤·à¤°à¥‹à¤‚ के साथ पाठ मान."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts the specified text value into a numeric value. Various forms that look like numbers (including digits followed by %, forms that look like dates, etc.) are handled. This may not handle all of the forms accepted by other spreadsheets and may be locale dependent. "
+msgstr "टà¥à¤°à¤¨à¥à¤•à¥‡à¤Ÿ दशमलव सà¥à¤¥à¤¾à¤¨à¥‹à¤‚ की निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ संखà¥à¤¯à¤¾ के लिठमान. यदि सटीक नकारातà¥à¤®à¤• है, 10 की शकà¥à¤¤à¤¿à¤¯à¥‹à¤‚ को टà¥à¤°à¤¨à¥à¤•à¥‡à¤Ÿ . "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values. "
+msgstr "संखà¥à¤¯à¤¾à¤¤à¥à¤®à¤• मूलà¥à¤¯à¥‹à¤‚ के नमूने विचरण लौट आया."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values. "
+msgstr "रिटरà¥à¤¨ सभी लोअरकेस में परिवरà¥à¤¤à¤¿à¤¤ अपरकेस अकà¥à¤·à¤°à¥‹à¤‚ के साथ पाठ मान. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain"
+msgstr "समतल"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph"
+msgstr "गà¥à¤°à¤¾à¤«"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Pie Chart"
+msgstr "पाइ चारà¥à¤Ÿ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cells to Graph"
+msgstr "गà¥à¤°à¤¾à¤« के लिठसेल"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "graph type"
+#msgstr "गà¥à¤°à¤¾à¤« पà¥à¤°à¤•à¤¾à¤°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Help"
+msgstr "सहायता"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal Bar"
+msgstr "कà¥à¤·à¥ˆà¤¤à¤¿à¤œ बार"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical Bar"
+msgstr "ऊरà¥à¤§à¥à¤µà¤¾à¤§à¤° बार"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Line Chart"
+msgstr "लाइन चारà¥à¤Ÿ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plot Points"
+msgstr "अनà¥à¤•à¤¿à¤¤ करो अंक"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "Not Set"
+#msgstr "सेट नहीं"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown range name"
+msgstr "अजà¥à¤žà¤¾à¤¤ शà¥à¤°à¥‡à¤£à¥€ नाम"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hide Help"
+msgstr "छिपाà¤à¤ सहायता"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Max "
+msgstr "अधिकतम"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Min "
+msgstr "मिन"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " OK "
+msgstr "ठीक है"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the column offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match>=value) instead of exact match. "
+msgstr "रेंज में दी मूलà¥à¤¯ के लिठमिलान मूलà¥à¤¯ के लिठदेखो और ऑफसेट कॉलम दà¥à¤µà¤¾à¤°à¤¾ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ सेल में इसी मूलà¥à¤¯ वापसी. यदि रैनà¥à¤œà¤²à¥à¤•à¤…प 1 (डिफ़ॉलà¥à¤Ÿ) और नहीं 0, अगर नà¥à¤¯à¥‚मेरिक कोषà¥à¤ à¤• के भीतर मैच है (मैच> मूलà¥à¤¯ =) के बजाय सटीक मेल का "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of week specified by the date value. If type is 1 (the default), Sunday is day and Saturday is day 7. If type is 2, Monday is day 1 and Sunday is day 7. If type is 3, Monday is day 0 and Sunday is day 6. "
+msgstr "वापसी की तारीख मूलà¥à¤¯ दà¥à¤µà¤¾à¤°à¤¾ निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ हफà¥à¤¤à¥‡ का दिन है. यदि पà¥à¤°à¤•à¤¾à¤° है 1 (डिफ़ॉलà¥à¤Ÿ), रविवार का दिन शनिवार है और 7 दिन है. यदि टाइप 2 है, सोमवार 1 दिन और रविवार 7 दिन है. यदि पà¥à¤°à¤•à¤¾à¤° 3 है, सोमवार 0 दिन और रविवार को 6 दिन है. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the year part of a date value. "
+msgstr "à¤à¤• तारीख मूलà¥à¤¯ का हिसà¥à¤¸à¤¾ वरà¥à¤· लौट आया. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date (an integer). Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "रिटरà¥à¤¨ आज की तारीख (à¤à¤• पूरà¥à¤£à¤¾à¤‚क). नोट: इस कारà¥à¤¯à¤•à¥à¤°à¤® में, 1 दिन 31 दिसमà¥à¤¬à¤° 1899 और 1900 साल है à¤à¤• छलांग वरà¥à¤· नहीं है. कà¥à¤› कारà¥à¤¯à¤•à¥à¤°à¤®à¥‹à¤‚ को 1 जनवरी 1900 का उपयोग करें, दिन के रूप में 1 और à¤à¤• छलांग के रूप में वरà¥à¤· 1900 का इलाज. दोनों ही मामलों में, हालाà¤à¤•à¤¿, पर या 1 मारà¥à¤š 1900 के बाद की तारीख, वही कर रहे हैं. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Date & Time"
+msgstr "दिनांक और समय"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Cancel]"
+msgstr "[रदà¥à¤¦ करें]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Verdana,Arial,Helvetica,sans-serif"
+msgstr "वरदना,à¤à¤°à¤¿à¤…ल,हेलवेटिका , सेंस -सेरिफ़"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "TRUE"
+msgstr "सच"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "FALSE"
+msgstr "गलत"
+
diff --git a/po/ja.po b/po/ja.po
new file mode 100644
index 0000000..f174076
--- /dev/null
+++ b/po/ja.po
@@ -0,0 +1,1473 @@
+# Copyright (C) 2010 THE PACKAGE"S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# olpc user <olpc@localhost.localdomain>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: SocialCalcActivity.activity\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-01-07 14:46+0000\n"
+"PO-Revision-Date: 2010-01-09 21:53+0530\n"
+"Last-Translator: Diksha<dksh.khatri@gmail.com>\n"
+"Language-Team: Hindi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: activity/activity.info:2
+msgid "SocialCalcActivity"
+msgstr "SocialCalcActivity"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:10
+#msgid "t"
+#msgstr "t"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:13
+msgid "Browser not supported. "
+msgstr "ブラウザãŒã‚µãƒãƒ¼ãƒˆã•ã‚Œã¾ã›ã‚“。 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:14
+msgid "Internal SocialCalc error (probably an internal bug):"
+msgstr "内部SocialCalcエラー(ãŠãらã内部ã®ãƒã‚°ï¼‰ï¼š"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:20
+msgid "Unknown col type item"
+msgstr "ä¸æ˜ŽCol種類ã®ã‚¢ã‚¤ãƒ†ãƒ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:21
+msgid "Unknown row type item"
+msgstr "未知ã®è¡Œã®ç¨®é¡žã®ã‚¢ã‚¤ãƒ†ãƒ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:22
+msgid "Unknown line type"
+msgstr "未知ã®è¡Œã‚’入力"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:28
+msgid "Unknown cell type item"
+msgstr "未知ã®ç´°èƒžã®ç¨®é¡žã®ã‚¢ã‚¤ãƒ†ãƒ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:36
+msgid "Unknown sheet command: "
+msgstr "ä¸æ˜Žãªã‚·ãƒ¼ãƒˆã®ã‚³ãƒžãƒ³ãƒ‰ï¼š "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:37
+msgid "Unknown set coord command: "
+msgstr "未知ã®åº§æ¨™ã‚³ãƒžãƒ³ãƒ‰ï¼š "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:38
+msgid "Unknown command: "
+msgstr "ä¸æ˜Žãªã‚³ãƒžãƒ³ãƒ‰ï¼š "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:42
+msgid "Circular reference to "
+msgstr "循環å‚ç…§ã™ã‚‹ãŸã‚ã« "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:52
+msgid "padding:2px 2px 1px 2px;vertical-align:top;"
+msgstr "パディング:2px 2px 1px 2px;ã®vertical - align:トップ;"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:53
+msgid "normal normal"
+msgstr "ノーマルノーマル"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:54
+msgid "small"
+msgstr "å°ã•ãª"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:55
+msgid "Verdana,Arial,Helvetica,sans-serif"
+msgstr "Verdana Arialãªã©ã¯ã€Helveticaã€ã‚µãƒ³ã‚»ãƒªãƒ•"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:92
+msgid "Render Context must have a sheet object"
+msgstr "レンダリングコンテキストシートオブジェクトãŒå¿…è¦ã§ã™"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Executing..."
+msgstr "実行..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Displaying..."
+msgstr "表示中..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Ordering..."
+msgstr "オーダー..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating..."
+msgstr "計算中ã§ã™..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating... Loading Sheet..."
+msgstr "計算中ã§ã™...読ã¿è¾¼ã‚“ã§ã‚·ãƒ¼ãƒˆ..."
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "doing server function "
+msgstr "サーãƒãƒ¼ã®æ©Ÿèƒ½ã‚’行ㆠ"
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " in cell "
+msgstr " セル内㮠"
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculation start..."
+msgstr "計算を開始..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SUM"
+msgstr "åˆè¨ˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Multi-line text: Click icon on right to edit]"
+msgstr "[複数行ã®ãƒ†ã‚­ã‚¹ãƒˆï¼šå³ç·¨é›†ã™ã‚‹ã‚’クリックã—ã¦ã‚¢ã‚¤ã‚³ãƒ³]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function "
+msgstr "ä¸æ˜Žãªé–¢æ•° "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane vertically"
+msgstr "åž‚ç›´æ–¹å‘ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã®ãƒ­ãƒƒã‚¯ã‚’ドラッグ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane horizontally"
+msgstr "水平方å‘ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã®ãƒ­ãƒƒã‚¯ã‚’ドラッグ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Center"
+msgstr "中央æƒãˆ"
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Left"
+msgstr "å·¦æƒãˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Right"
+msgstr "å³æƒãˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Alignment"
+msgstr "アライメント"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit"
+msgstr "監査"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit Trail This Session"
+msgstr "監査証跡ã“ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto"
+msgstr "オート"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto Sum"
+msgstr "自動車åˆè¨ˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto w/ commas"
+msgstr "自動ワット/コンマ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Automatic"
+msgstr "自動"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Background"
+msgstr "背景"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold"
+msgstr "太字"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold &amp; Italics"
+msgstr "ボールド&イタリック体"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold Italic"
+msgstr "太字斜体"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders"
+msgstr "境界線"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders Off"
+msgstr "国境をオフ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders On"
+msgstr "国境ã§"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom"
+msgstr "底"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom Border"
+msgstr "下ã®ãƒœãƒ¼ãƒ€ãƒ¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CELL SETTINGS"
+msgstr "セル設定"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CSV format"
+msgstr "CSVå½¢å¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cancel"
+msgstr "キャンセル"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Category"
+msgstr "カテゴリー"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Center"
+msgstr "センター"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear"
+msgstr "片付ã‘ã‚‹"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear SocialCalc Clipboard"
+msgstr "クリアSocialCalcクリップ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clipboard"
+msgstr "クリップボード"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Color"
+msgstr "カラー"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Column"
+msgstr "列"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Comment"
+msgstr "コメント"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Copy"
+msgstr "コピー"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Custom"
+msgstr "風習"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cut"
+msgstr "切る"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default"
+msgstr "債務ä¸å±¥è¡Œ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Alignment"
+msgstr "デフォルトã®ã‚¢ãƒ©ã‚¤ãƒ³ãƒ¡ãƒ³ãƒˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Column Width"
+msgstr "デフォルトã®åˆ—å¹…"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Font"
+msgstr "Fデフォルトã®ãƒ•ã‚©ãƒ³ãƒˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Format"
+msgstr "既定ã®å½¢å¼]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Padding"
+msgstr "デフォルトã®ãƒ‘ディング"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete"
+msgstr "削除ã™ã‚‹"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Column"
+msgstr "列を削除"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Contents"
+msgstr "コンテンツを削除"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Row"
+msgstr "è¡Œã®å‰Šé™¤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Description"
+msgstr "商å“概è¦"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Display Clipboard in"
+msgstr "ディスプレイクリップボード内ã®"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Down"
+msgstr "下ã«"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Edit"
+msgstr "[編集]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Existing Names"
+msgstr "既存ã®å“å"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Family"
+msgstr "家æ—"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Down"
+msgstr "フィルダウン"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Right"
+msgstr "å¡—ã‚Šã¤ã¶ã—å³"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Font"
+msgstr "フォント"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Format"
+msgstr "フォーマット"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula"
+msgstr "æ•°å¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Function List"
+msgstr "機能一覧"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Functions"
+msgstr "関数"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Grid"
+msgstr "グリッド"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hidden"
+msgstr "éš ã—"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal"
+msgstr "水平方å‘ã®"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Column"
+msgstr "列ã®æŒ¿å…¥"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Row"
+msgstr "è¡Œã®æŒ¿å…¥"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Italic"
+msgstr "イタリック体"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Last Sort"
+msgstr "最後ã®ä¸¦ã¹æ›¿ãˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left"
+msgstr "å·¦"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left Border"
+msgstr "左罫線"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link"
+msgstr "リンク"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link Input Box"
+msgstr "リンク入力ボックス"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "List"
+msgstr "一覧"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Load SocialCalc Clipboard With This"
+msgstr "è² è·SocialCalcクリップã“ã®ã¨"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Major Sort"
+msgstr "主ãªä¸¦ã¹æ›¿ãˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Manual"
+msgstr "マニュアル"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Merge Cells"
+msgstr "セルã®çµåˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Middle"
+msgstr "中æ±"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Minor Sort"
+msgstr "マイナーã®ä¸¦ã¹æ›¿ãˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Insert"
+msgstr "挿入移動"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Paste"
+msgstr "貼り付ã‘移動"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Multi-line Input Box"
+msgstr "複数行ã®å…¥åŠ›ãƒœãƒƒã‚¯ã‚¹"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Name"
+msgstr "åå‰"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Names"
+msgstr "å“å"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "No padding"
+msgstr "パディングãªã—"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Normal"
+msgstr "ノーマル"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number"
+msgstr "å“番"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number Horizontal"
+msgstr "æ•°æ°´å¹³"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "OK"
+msgstr "[OK]ã‚’"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Padding"
+msgstr "パディング"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Page Name"
+msgstr "ページå"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste"
+msgstr "貼り付ã‘"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste Formats"
+msgstr "貼り付ã‘ã‚‹å½¢å¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain Text"
+msgstr "プレーンテキスト"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalc"
+msgstr "å†è¨ˆç®—"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalculation"
+msgstr "å†è¨ˆç®—"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " Redo"
+msgstr " REDOログ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right"
+msgstr "å³"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right Border"
+msgstr "å³æž "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SHEET SETTINGS"
+msgstr "シートã®è¨­å®š"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save"
+msgstr "ä¿å­˜ã™ã‚‹"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save to"
+msgstr "ã«ä¿å­˜ã™ã‚‹"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cell Contents"
+msgstr "設定ã™ã‚‹ã‚»ãƒ«ã®å†…容"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Sort"
+msgstr "設定ã™ã‚‹ã‚»ãƒ«ã«ä¸¦ã¹æ›¿ãˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Value To"
+msgstr "値ã®è¨­å®šã™ã‚‹ã«ã¯"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set to Link format"
+msgstr "を設定ã™ã‚‹ãƒªãƒ³ã‚¯ã®ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set/Clear Move From"
+msgstr "セット/クリアã‹ã‚‰ç§»å‹•"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Cell Settings"
+msgstr "表示ã™ã‚‹ã‚»ãƒ«ã®è¨­å®š"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Sheet Settings"
+msgstr "表示シートã®è¨­å®š"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show in new browser window"
+msgstr "表示ã™ã‚‹æ–°ã—ã„ブラウザウィンドウã§"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Size"
+msgstr "寸法"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SocialCalc-save format"
+msgstr "SocialCalc -å½¢å¼ã§ä¿å­˜ã™ã‚‹"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort"
+msgstr "並ã¹æ›¿ãˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort Cells"
+msgstr "並ã¹æ›¿ãˆã®ã‚»ãƒ«"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Swap Colors"
+msgstr "スワップã®è‰²"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Tab-delimited format"
+msgstr "タブ区切り形å¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text"
+msgstr "テキスト"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text Horizontal"
+msgstr "テキストã®æ°´å¹³æ–¹å‘ã®"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "This is a<br>sample"
+msgstr "ã“ã‚Œã¯<br>サンプル"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top"
+msgstr "頂上"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top Border"
+msgstr "トップボーダー"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "UNDONE STEPS"
+msgstr "å…ƒã«æˆ»ã™æ‰‹é †"
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "URL"
+msgstr "URLã‚’"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Undo"
+msgstr "å…ƒã«æˆ»ã™"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unmerge Cells"
+msgstr "をunmerge細胞"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Up"
+msgstr "上ã¸"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Value"
+msgstr "値"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical"
+msgstr "åž‚ç›´"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Workspace"
+msgstr "ワークスペース"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[New]"
+msgstr "[æ–°è¦]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[None]"
+msgstr "[ãªã—]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[select range]"
+msgstr "[é¸æŠžç¯„囲]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
+#msgstr ["日曜日"ã€"月"ã€"ç«"ã€"æ°´"ã€"木"ã€"金曜日"ã€"土"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
+#msgstr ["æ—¥"ã€"月"ã€"ç«"ã€"æ°´"ã€"木"ã€"金"ã€"土"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["January", "February", "March", "April", "May", "June", "July", "August", "September","October", "November", "December"]
+#msgstr ["1月"ã€"2"ã€"3月"ã€"4"ã€"5月"ã€"6月"ã€"7"ã€"8月"ã€"9月"ã€"10"ã€"11"ã€"12"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+#msgstr ["01"ã€"2月"ã€"03"ã€"4月"ã€"5"ã€"6月"ã€"7月"ã€"8月"ã€"9月"ã€"10月"ã€"11月"ã€"12月"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "AM"
+#msgstr "åˆå‰"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "A"
+#msgstr "A"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "PM"
+#msgstr "åˆå¾Œ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "P"
+#msgstr "P"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed number exponent"
+msgstr "ä¸é©åˆ‡ãªæ•°ã®æŒ‡æ•°ã‚’å½¢æˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unexpected character in formula"
+msgstr "å¼ã®ä¸­ã§ã€äºˆæœŸã—ãªã„文字"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed string"
+msgstr "ä¸é©åˆ‡ãªæ–‡å­—列ã®å½¢æˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed special value"
+msgstr "ä¸é©åˆ‡ãªå€¤ã‚’å½¢æˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula (two operators inappropriately in a row)"
+msgstr "エラーã®æ•°å¼ã§è¡Œï¼ˆ2ã¤ã®æ¼”ç®—ãŒä¸é©åˆ‡ï¼‰ã®"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing open parenthesis in list with comma(s)."
+msgstr "カンマã§åŒºåˆ‡ã£ã¦ãƒªã‚¹ãƒˆã«é–‹ã括弧ãŒä¸è¶³ï¼ˆç§’)。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Closing parenthesis without open parenthesis. "
+msgstr "é–‹ã括弧ãªã—ã§é–‰ä¼šæ‹¬å¼§ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing close parenthesis."
+msgstr "é–‰ã˜æ‹¬å¼§ãŒã‚ã‚Šã¾ã›ã‚“。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing operand."
+msgstr "オペランドãŒã‚ã‚Šã¾ã›ã‚“。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula."
+msgstr "æ•°å¼ã«ã‚¨ãƒ©ãƒ¼ãŒã‚ã‚Šã¾ã™ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error value in formula"
+msgstr "æ•°å¼ã§ã‚¨ãƒ©ãƒ¼å€¤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula resulting in bad value"
+msgstr "エラーã®æ•°å¼ã§ä¸æ­£ãªå€¤ã®çµæžœ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in range value:"
+msgstr "範囲ã®å€¤ã«æ•°å¼ã®çµæžœï¼š"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in an bad numeric value"
+msgstr "悪ã„数値ã«F1ã®çµæžœ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Numeric overflow"
+msgstr "数値ã®ã‚ªãƒ¼ãƒãƒ¼ãƒ•ãƒ­ãƒ¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet unavailable:"
+msgstr "シートãŒä½¿ç”¨ã§ããªã„:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cell reference missing when expected."
+msgstr "セルå‚照時ã«äºˆæƒ³ã•ãŒãªã„。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet name missing when expected."
+msgstr "シートåãŒäºˆæƒ³ã•ãŒãªã„。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Circular name reference to name"
+msgstr "円形ã®åå‰ã®å‚ç…§ã®åå‰ã«"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown name"
+msgstr "åå‰ãŒä¸æ˜Žã§ã™"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Incorrect arguments to function"
+msgstr "ä¸é©åˆ‡ãªé–¢æ•°ã®å¼•æ•°ã«"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function"
+msgstr "ä¸æ˜Žãªé–¢æ•°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LN argument must be greater than 0"
+msgstr "LNã®å¼•æ•°ãŒ0より大ãã„å¿…è¦ãŒã‚ã‚Šã¾ã™"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG10 argument must be greater than 0"
+msgstr "LOG10引数ã¯ã€0より大ãã„å¿…è¦ãŒã‚ã‚Šã¾ã™"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG second argument must be numeric greater than 0"
+msgstr "ログ2番目ã®å¼•æ•°ã¯ã€0より大ãã„数値ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG first argument must be greater than 0"
+msgstr "ログ最åˆã®å¼•æ•°ã¯ã€0より大ãã„å¿…è¦ãŒã‚ã‚Šã¾ã™"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "ROUND second argument must be numeric"
+msgstr "ラウンド2番目ã®å¼•æ•°ã¯æ•°å€¤ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "DDB life must be greater than 1"
+msgstr "DDBã«å¯¿å‘½ãŒ1よりも大ãããªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SLN life must be greater than 1"
+msgstr "slnファイルã®ç”Ÿæ´»ãŒ1よりも大ãããªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Absolute value function. "
+msgstr "絶対値関数。 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arccosine function. "
+msgstr "三角関数ã®é€†ä½™å¼¦é–¢æ•°ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if all arguments are true. "
+msgstr "ã™ã¹ã¦ã®å¼•æ•°ãŒçœŸã¯True。 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arcsine function. "
+msgstr "三角関数ã®ã‚¢ãƒ¼ã‚¯ã‚µã‚¤ãƒ³é–¢æ•°ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arctan function. "
+msgstr "三角関数ã®é€†æ­£æŽ¥é–¢æ•°é–¢æ•°ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arc tangent function (result is in radians). "
+msgstr "三角関数ã®ã‚¢ãƒ¼ã‚¯ã‚¿ãƒ³ã‚¸ã‚§ãƒ³ãƒˆé–¢æ•°ï¼ˆçµæžœã¯ãƒ©ã‚¸ã‚¢ãƒ³å˜ä½ï¼‰ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values. "
+msgstr "ã®å¹³å‡å€¤ã§ã™ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value specified by the index. The values may be ranges of cells. "
+msgstr "戻り値ã¯ã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§æŒ‡å®šã•ã‚ŒãŸã€‚ã®å€¤ã¯ã€ã‚»ãƒ«ã®ç¯„囲ãŒã‚ã‚Šã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of columns in the range. "
+msgstr "ã®ç¯„囲内ã®åˆ—ã®æ•°ã‚’è¿”ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric cosine function (value is in radians). "
+msgstr "三角関数ã®ä½™å¼¦é–¢æ•°ï¼ˆå€¤ã¯ãƒ©ã‚¸ã‚¢ãƒ³ã§ï¼‰ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error. "
+msgstr "数値ã®å€¤ã®æ•°ã¯ã€ç©ºç™½ã§ã¯ãªãã€ãƒ†ã‚­ã‚¹ãƒˆã€ã¾ãŸã¯ã‚¨ãƒ©ãƒ¼ã‚’カウントã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values. "
+msgstr "以外ã®æ•°ãŒç©ºç™½ã®å€¤ã‚’カウントã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of blank values. (Note: '' is not blank.) "
+msgstr "空白ã®å€¤ã®æ•°ã‚’カウントã—ã¾ã™ã€‚ (注:''ã€ç©ºç™½ã¯ã‚ã‚Šã¾ã›ã‚“。) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of number of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). "
+msgstr "範囲内ã®ã‚»ãƒ«ã®æ•°ã®æ•°ãŒåŸºæº–を満ãŸã—ã¦ã‚«ã‚¦ãƒ³ãƒˆã—ã¾ã™ã€‚基準値ã§ã‚ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ï¼ˆ'x'ã‚’ã€15ã€1 3)ã€ã¾ãŸã¯ãƒ†ã‚¹ãƒˆï¼ˆ25)。 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the appropriate date value given numbers for year, month, and day. For example: DATE(2006,2,1) for February 1, 2006. Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "å¹´é–“ã®æˆ»ã‚Šå€¤ã¯ã€é©åˆ‡ãªæ—¥ä»˜ã®å€¤ã‚’指定ã•ã‚ŒãŸæ•°å­—ã€æœˆã€æ—¥ã€‚例:日付(2006,2,1)2006å¹´2月1æ—¥ã§ã™ã€‚注:ã“ã®ãƒ—ログラムã§ã¯ã€1日目1899å¹´12月31æ—¥ãŠã‚ˆã³1900å¹´ã¯ã†ã‚‹ã†å¹´ã§ã¯ã‚ã‚Šã¾ã›ã‚“。一部ã®ãƒ—ログラムã¯1900å¹´1月1æ—¥ã€1日目ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ã¨ã€ã†ã‚‹ã†å¹´ã¨ã—ã¦1900扱ã„ã¾ã™ã€‚両方ã®ã‚±ãƒ¼ã‚¹ã§ã¯ã€ã—ã‹ã—ã€ã¾ãŸã¯1900å¹´3月1日以é™ã®æ—¥ä»˜ã¯ã€åŒã˜ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values in the specified field in records that meet the criteria. "
+msgstr "å¹³å‡ãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®æŒ‡å®šã•ã‚ŒãŸãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã®å€¤ãŒåŸºæº–を満ãŸã—ã¦ã„ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of month for a date value. "
+msgstr "日付ã®å€¤ã‚’è¿”ã—ã¾ã™æœˆã®æ—¥ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error, in the specified field in records that meet the criteria. "
+msgstr "数値ã®å€¤ã®æ•°ã¯ã€ç©ºç™½ã§ã¯ãªãã€ãƒ†ã‚­ã‚¹ãƒˆã€ã¾ãŸã¯ã‚¨ãƒ©ãƒ¼ã®ãŸã‚ã€æŒ‡å®šã•ã‚ŒãŸãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰å†…ã®ãƒ¬ã‚³ãƒ¼ãƒ‰ã§ã¯åŸºæº–を満ãŸã—ã¦ã‚«ã‚¦ãƒ³ãƒˆã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values in the specified field in records that meet the criteria. "
+msgstr "以外ã®ç•ªå·ã‚’空白ã®å€¤ã¯ã€æŒ‡å®šã•ã‚ŒãŸãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰å†…ã®ãƒ¬ã‚³ãƒ¼ãƒ‰ã§ã¯åŸºæº–を満ãŸã—ã¦ã‚«ã‚¦ãƒ³ãƒˆã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at the given period of time (the default factor is 2 for double-declining balance). "
+msgstr "ã®æ™‚間を指定ã•ã‚ŒãŸæœŸé–“ã‚’è¿”ã—ã¾ã™æ¸›ä¾¡å„Ÿå´è²»ã®é¡ï¼ˆãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ã¯å› å­2å€å®šçŽ‡æ³•ã§ã™ï¼‰ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in radians into degrees. "
+msgstr "度をラジアンå˜ä½ã®å€¤ã«å¤‰æ›ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value of the specified field in the single record that meets the criteria. "
+msgstr "ãã®åŸºæº–を満ãŸã—ã¦ã„ã‚‹1ã¤ã®ãƒ¬ã‚³ãƒ¼ãƒ‰ã§æŒ‡å®šã•ã‚ŒãŸãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã®å€¤ã‚’è¿”ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "戻り値ã®ãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®æŒ‡å®šã•ã‚ŒãŸãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰å†…ã®æ•°å€¤ã®å€¤ã®æœ€å¤§å€¤ã¯ã€åŸºæº–を満ãŸã—ã¦ã„ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values in the specified field in records that meet the criteria. "
+msgstr "レコードを返ã™ã«ã¯ã€æ¡ä»¶ã‚’満ãŸã™ã€æŒ‡å®šã•ã‚ŒãŸãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«æ•°å€¤ã‚’ä¹—ç®—ã—ãŸçµæžœã‚’è¿”ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "レコード内ã®æŒ‡å®šã•ã‚ŒãŸãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰å†…ã®æ•°å€¤ã®æˆ»ã‚Šå€¤ã¯ã€ã‚µãƒ³ãƒ—ルã®æ¨™æº–åå·®ã¯ã€åŸºæº–を満ãŸã—ã¦ã„ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "戻り値ã®ãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®æŒ‡å®šã•ã‚ŒãŸãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã®æ•°å€¤ã®å€¤ã®æ¨™æº–åå·®ã¯ã€åŸºæº–を満ãŸã—ã¦ã„ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "戻り値ã®ãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®æŒ‡å®šã•ã‚ŒãŸãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã®æ•°å€¤ã®å€¤ã®åˆè¨ˆã¯ã€åŸºæº–を満ãŸã—ã¦ã„ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "戻り値ã®ãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®æŒ‡å®šã•ã‚ŒãŸãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰å†…ã®æ•°å€¤ã®æ¨™æœ¬åˆ†æ•£ã¯åŸºæº–を満ãŸã—ã¦ã„ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "戻り値ã®ãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®æŒ‡å®šã•ã‚ŒãŸãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰å†…ã®æ•°å€¤ã®å·®ç•°ã¯ã€åŸºæº–を満ãŸã—ã¦ã„ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest even integer. "
+msgstr "最も近ã„大ãã•ã«ä¸¸ã‚ã‚‹ã®å€¤ã‚’å¶æ•°ã®æ•´æ•°ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the values are exactly the same, including case, type, etc. "
+msgstr "trueã‚’è¿”ã—ã¾ã™æ­£ç¢ºã«ã€å¤§æ–‡å­—ã¨å°æ–‡å­—ã€ã‚¿ã‚¤ãƒ—ã€ãªã©ã‚’å«ã‚€ã¨åŒã˜å ´åˆã¯ã€å€¤ã¯ã€ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns e raised to the value power. "
+msgstr "戻り値eã¯ã€å€¤ã®é›»åŠ›ã‚’調é”ã—ãŸã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns factorial of the value. "
+msgstr "戻り値ã®éšŽä¹—を。 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value false. "
+msgstr "戻り値ã®è«–ç†å€¤ã¯falseã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the starting position within string2 of the first occurrence of string1 at or after start. If start is omitted, 1 is assumed. "
+msgstr "戻り値ã§ã€ã¾ãŸã¯é–‹å§‹å¾Œstring2ãŒstring1ã®æœ€åˆã®å‡ºç¾ä»¥å†…ã«é–‹å§‹ä½ç½®ã€‚ startãŒçœç•¥ã•ã‚ŒãŸå ´åˆã€1ãŒæƒ³å®šã•ã‚Œã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the future value of repeated payments of money invested at the given rate for the specified number of periods, with optional present value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "期間ã®çµ‚ã‚ã‚Š=ã§ã‚ªãƒ—ションã®ç¾åœ¨ã®å€¤ï¼ˆãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã¯0)ã¨ãŠæ”¯æ‰•ã„ã®ç¨®é¡žã¨ä¾¡æ ¼ã®æœŸé–“ã®æŒ‡å®šã•ã‚ŒãŸç•ªå·ã«ã¤ã„ã¦ã¯ã€æŒ‡å®šã•ã‚ŒãŸãƒ¬ãƒ¼ãƒˆã§ã®æŠ•è³‡ã‚’ç¹°ã‚Šè¿”ã—ã¦æ”¯æ‰•ã„ã®æˆ»ã‚Šå€¤ã¯ã€å°†æ¥ä¾¡å€¤ã€ï¼ˆãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã¯0ã§ã€1期ã®å§‹ã¾ã‚Š=)。 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the row offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. "
+msgstr "範囲内ã§æŒ‡å®šã•ã‚ŒãŸå€¤ã¯ã€ä¸€è‡´ã™ã‚‹å€¤ã‚’検索ã—ã¦ã€ã‚»ãƒ«ã®è¡Œã®ã‚ªãƒ•ã‚»ãƒƒãƒˆã§æŒ‡å®šã•ã‚ŒãŸå¯¾å¿œã™ã‚‹å€¤ã‚’è¿”ã—ã¾ã™ã€‚ã‚‚ã—rangelookup 1(デフォルト)ã¨0ã§ã¯ãªãã€æ•°å€¤ã€æ‹¬å¼§ã®å ´åˆã«ä¸€è‡´ã™ã‚‹ï¼ˆä¸€è‡´= value)ã¨æ­£ç¢ºã«ä¸€è‡´ã™ã‚‹ã®ä»£ã‚ã‚Šã«ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the hour portion of a time or date/time value. "
+msgstr "時刻ã¾ãŸã¯æ—¥ä»˜ã‚’è¿”ã—ã¾ã™æ™‚間部分/時刻ã®å€¤ã‚’è¿”ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Results in true-value if logical-expression is TRUE or non-zero, otherwise results in false-value. "
+msgstr "真ã®å€¤ã®ä¸­ã®å ´åˆã€è«–ç†å¼ãŒTRUEã®å ´åˆã€éžã‚¼ãƒ­ã®å ´åˆã¯falseを値ã®çµæžœã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns a cell or range reference for the specified row and column in the range. If range is 1-dimensional, then only one of rownum or colnum are needed. If range is 2-dimensional and rownum or colnum are zero, a reference to the range of just the specified column or row is returned. You can use the returned reference value in a range, e.g., sum(A1:INDEX(A2:A10,4)). "
+msgstr "範囲内ã§æŒ‡å®šã•ã‚ŒãŸè¡Œã‚„列を返ã—ã¾ã™ã‚»ãƒ«ã¾ãŸã¯ã‚»ãƒ«ç¯„囲ã®å‚ç…§ã§ã™ã€‚å ´åˆã€ç¯„囲ã¯ã€1次元ã®å ´åˆã€1ã¤ã ã‘rownumã¯ã€ã¾ãŸã¯colnumã®ã«å¿…è¦ãªã“ã¨ã§ã™ã€‚å ´åˆã€ç¯„囲ã¯ã€2次元ãŠã‚ˆã³ROWNUMã¾ãŸã¯colnumゼロã§ã‚ã‚‹ãªã‚‰ã€å˜ã«æŒ‡å®šã•ã‚ŒãŸåˆ—ã¾ãŸã¯è¡Œã®ç¯„囲ã¸ã®å‚ç…§ãŒè¿”ã•ã‚Œã¾ã™ã€‚ç¾åœ¨ã®ç¯„囲ã§ã€ï¼ˆA1を:インデックス(a2ã®ï¼šA10ã«ã€4))ã®åˆè¨ˆä¾‹ãˆã°ã€è¿”ã•ã‚Œã‚‹å‚照値を使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value rounded down to the nearest integer (towards -infinity). "
+msgstr "戻り値ã¯ã€æœ€ã‚‚è¿‘ã„æ•´æ•°ã«å››æ¨äº”入(ã¸ã®ç„¡é™å¤§ï¼‰ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the interest rate at which the cash flows in the range have a net present value of zero. Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "戻り値ã®ç¾é‡‘ã®ç¯„囲ã§æµã‚Œã¦é‡‘利ãŒã‚¼ãƒ­ã®æ­£å‘³ç¾åœ¨ä¾¡å€¤ãŒã‚る。ã¯ã«ï¼ƒNUMã‚’è¿”ã—ã¾ã™ã€‚å復プロセスを使用ã—ã¦ï¼ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ãªã„å ´åˆã¯åŽæŸã™ã‚‹ã€‚ 2ã¤ä»¥ä¸Šå¯èƒ½ãªè§£æ±ºç­–ã«ãªã‚‹ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚特定ã®çŠ¶æ³ã§ã¯ãã‚Œã¯ãªã„åŽæŸã‚’助ã‘ã‚‹ã‹ã‚‚ã—ã‚Œãªã„ã€ã¾ãŸã¯ä¸é©åˆ‡ãªè§£ã‚’求ã‚るオプションã®æŽ¨æ¸¬å€¤ã‚’æä¾›ã™ã‚‹ï¼ˆãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ã¯æŽ¨æ¸¬10%)ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is a reference to a blank cell. "
+msgstr "ãŒtrueã‚’è¿”ã™å ´åˆã€å€¤ã¯ç©ºç™½ã®ã‚»ãƒ«ã¸ã®å‚ç…§ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error but not NA. "
+msgstr "ãŒtrueã‚’è¿”ã™å ´åˆã¯ã€å€¤ã®åž‹ã®ã‚¨ãƒ©ãƒ¼ã§ã¯ãªãã€NAã®ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error. "
+msgstr "ãŒtrueã‚’è¿”ã™å ´åˆã¯ã€å€¤ã®åž‹ã‚¨ãƒ©ãƒ¼ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Logical (true/false). "
+msgstr "ãŒtrueã‚’è¿”ã™å ´åˆã¯ã€å€¤åž‹ã®è«–ç†ãŒã—ã¾ã™ï¼ˆtrue / false)ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is the error type NA. "
+msgstr "ãŒtrueã‚’è¿”ã™å ´åˆã€å€¤ã¯ã€ã‚¨ãƒ©ãƒ¼ã®ç¨®é¡žã¯NAã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is not of type Text. "
+msgstr "ãŒtrueã‚’è¿”ã™å ´åˆã¯ã€å€¤ã‚’入力ã—ãªã„ã§ãƒ†ã‚­ã‚¹ãƒˆã®ä¸€ã¤ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Number (including logical values). "
+msgstr "ãŒtrueã‚’è¿”ã™å ´åˆã¯ã€å€¤ã®åž‹ã®æ•°ï¼ˆè«–ç†å€¤ã‚’å«ã‚€ï¼‰ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Text. "
+msgstr "ãŒtrueã‚’è¿”ã™å ´åˆã¯ã€å€¤ã®åž‹ã®ãƒ†ã‚­ã‚¹ãƒˆã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value. If count is omitted, 1 is assumed. "
+msgstr "テキスト値ã‹ã‚‰æ–‡å­—ã®æˆ»ã‚Šå€¤ã¯ã€æŒ‡å®šã—ãŸæ•°ã§ã™ã€‚ countã‚’çœç•¥ã™ã‚‹ã¨ã€1ã¨ã¿ãªã•ã‚Œã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of characters in the text value. "
+msgstr "テキスト値ã®ä¸­ã®æ–‡å­—ã®æ•°ã‚’è¿”ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the natural logarithm of the value. "
+msgstr "戻り値ã®è‡ªç„¶å¯¾æ•°ã‚’è¿”ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logarithm of the value using the specified base. "
+msgstr "戻り値ã®å¯¾æ•°ã«æŒ‡å®šã•ã‚ŒãŸãƒ™ãƒ¼ã‚¹ã‚’使用ã—ã¦ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the base 10 logarithm of the value. "
+msgstr "戻り値ã¯ã€åŸºæœ¬å€¤ã®10対数を返ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all uppercase characters converted to lowercase. "
+msgstr "ã™ã¹ã¦ã®å¤§æ–‡å­—ã‚’å°æ–‡å­—ã«å¤‰æ›ã—ã¦ãƒ†ã‚­ã‚¹ãƒˆã‚’è¿”ã—ã¾ã™å€¤ã‚’è¿”ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return position (the first is 1) in that range. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. If rangelookup is -1, act like 1 but the bracket is match>=value. "
+msgstr "範囲内ã§æŒ‡å®šã•ã‚ŒãŸå€¤ã¨æˆ»ã‚Šå€¤ã®ä½ç½®ã«ä¸€è‡´ã™ã‚‹å€¤ã‚’探ã—ã¾ã™ï¼ˆæœ€åˆã®1)ã¯ã€ç¯„囲内ã§ã™ã€‚ã‚‚ã—rangelookup 1(デフォルト)ã¨0ã§ã¯ãªãã€æ•°å€¤ã€æ‹¬å¼§ã®å ´åˆã«ä¸€è‡´ã™ã‚‹ï¼ˆä¸€è‡´= value)ã¨æ­£ç¢ºã«ä¸€è‡´ã™ã‚‹ã®ä»£ã‚ã‚Šã«ã€‚ã‚‚ã—rangelookup -1ã€1ã®ã‚ˆã†ã«æŒ¯ã‚‹èˆžã†ãŒã€ãƒ–ラケットã®ä¸€è‡´= valueã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values. "
+msgstr "戻り値ã¯ã€æ•°å€¤å€¤ã®æœ€å¤§å€¤ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the specified position. "
+msgstr "テキスト値ã¯ã€æŒ‡å®šã•ã‚ŒãŸä½ç½®ã‹ã‚‰ã‚¹ã‚¿ãƒ¼ãƒˆã™ã‚‹ã‹ã‚‰æ–‡å­—ã®æˆ»ã‚Šå€¤ã¯ã€æŒ‡å®šã—ãŸæ•°ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minimum of the numeric values. "
+msgstr "戻り値ã¯ã€æ•°å€¤ã®å€¤ã®æœ€å°å€¤ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minute portion of a time or date/time value. "
+msgstr "時刻ã¾ãŸã¯æ—¥ä»˜ã‚’è¿”ã—ã¾ã™åˆ†ã®éƒ¨åˆ†ã‚’/時刻ã®å€¤ã‚’è¿”ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the remainder of the first value divided by the second. "
+msgstr "戻り値ã®æœ€åˆã®å€¤ã€2番目ã§å‰²ã£ãŸå€¤ã®æ®‹ã‚Šã®éƒ¨åˆ†ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the month part of a date value. "
+msgstr "戻り値ã®æ—¥ä»˜ã®å€¤ã®æœˆã®éƒ¨åˆ†ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value if it is a numeric value otherwise an error. "
+msgstr "値を返ã™å ´åˆã¯ã€æ•°å€¤ä»¥å¤–ã¯ã‚¨ãƒ©ãƒ¼ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the #N/A error value which propagates through most operations. "
+msgstr "戻り値ã¯ã€ï¼ƒN /ã¯ã€ã»ã¨ã‚“ã©ã®æ“作を介ã—ã¦ä¼æ’­ã™ã‚‹ã‚¨ãƒ©ãƒ¼å€¤ã‚’è¿”ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns FALSE if value is true, and TRUE if it is false. "
+msgstr "å ´åˆã€å€¤ã¯trueã§ã™æˆ»ã‚Šå€¤ã¯FALSEã¨ãã‚ŒãŒfalseã®å ´åˆã¯TRUEã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date/time. "
+msgstr "戻り値ã¯ã€ç¾åœ¨ã®æ—¥ä»˜/時刻。 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of periods at which payments invested each period at the given rate with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period) has the given present value. "
+msgstr "ã“ã‚Œã§ãŠæ”¯æ‰•ã„オプションã®å°†æ¥ã®å€¤ï¼ˆãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã¯0)ã¨ãŠæ”¯æ‰•ã„ã®ç¨®é¡žã‚’使用ã—ã¦æŒ‡å®šã•ã‚ŒãŸãƒ¬ãƒ¼ãƒˆï¼ˆãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã¯0期ã®çµ‚ã‚ã‚Š=ã§ã€1期ã®å§‹ã¾ã‚Š=)ã€å„期間ã®æŠ•è³‡æœŸé–“ã®æ•°ã‚’è¿”ã™ã€æŒ‡å®šã•ã‚ŒãŸç¾åœ¨ã®å€¤ã‚’æŒã¡ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the net present value of cash flows (which may be individual values and/or ranges) at the given rate. The flows are positive if income, negative if paid out, and are assumed at the end of each period. "
+msgstr "キャッシュフローã®æˆ»ã‚Šå€¤ã¯ã€æ­£å‘³ç¾åœ¨ä¾¡å€¤ï¼ˆã“ã‚Œã¯å€‹ã€…ã®å€¤ãŠã‚ˆã³/ã¾ãŸã¯ç¯„囲)を指定ã•ã‚ŒãŸãƒ¬ãƒ¼ãƒˆã§ã‚Œã‚‹ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚å ´åˆã«æ”¯æ‰•ã‚å ´åˆã€æ‰€å¾—ã€è² ã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ãƒ•ãƒ­ãƒ¼ã¯ã€ãƒ—ラスã•ã‚Œã€å„時代ã®çµ‚ã‚ã‚Šã¨è¦‹ãªã•ã‚Œã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest odd integer. "
+msgstr "最も近ã„奇数ã®æ•´æ•°ã®å¤§ãã•ã«ä¸¸ã‚ã‚‹ã®å€¤ã‚’ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if any argument is true "
+msgstr "true trueã®å ´åˆã€ä»»æ„ã®å¼•æ•°ã§ã™ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "The value 3.1415926... "
+msgstr "ã“ã®å€¤ã¯3.1415926 ... "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of each payment that must be invested at the given rate for the specified number of periods to have the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "戻り値ã¯ã€æœŸé–“ã®æŒ‡å®šã•ã‚ŒãŸç•ªå·ã«ã¤ã„ã¦ã¯ã€æŒ‡å®šã•ã‚ŒãŸãƒ¬ãƒ¼ãƒˆã§æŒ‡å®šã•ã‚ŒãŸç¾åœ¨ã®å€¤ã‚’æŒã¤ã€ã‚ªãƒ—ションã®å°†æ¥ã®å€¤ï¼ˆãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã¯0)ã¨æ”¯æ‰•ã‚¿ã‚¤ãƒ—(デフォルトã¯0期ã®çµ‚ã‚ã‚Š=ã§ã€1 =最åˆã«æŠ•è³‡ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™å„ãŠæ”¯æ‰•ã„ã®é‡‘é¡æœŸé–“)。 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the first value raised to the second value power. "
+msgstr "戻り値ã®æœ€åˆã®å€¤ã¯ã€2番目ã®å€¤ã¯é›»æºã‚’調é”ã—ãŸã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values. "
+msgstr "戻り値ã¯ã€æ•°å€¤ã®å€¤ã‚’ä¹—ç®—ã—ãŸçµæžœã‚’è¿”ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with the first letter of each word converted to uppercase and the others to lowercase. "
+msgstr "å„å˜èªžã‚’大文字ã«ã€ä»–ã¯å°æ–‡å­—ã«å¤‰æ›ã®æœ€åˆã®æ–‡å­—ã‚’è¿”ã—ã¾ã™ãƒ†ã‚­ã‚¹ãƒˆå€¤ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the present value of the given number of payments each invested at the given rate, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "ã®æ”¯æ‰•ã„を指定ã•ã‚ŒãŸæ•°ã‚’è¿”ã—ã¾ã™ç¾åœ¨ã®å€¤ã¯ã€å„指定ã•ã‚ŒãŸãƒ¬ãƒ¼ãƒˆã§ã€ã‚ªãƒ—ションã®å°†æ¥ã®å€¤ï¼ˆãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã¯0)ã¨æ”¯æ‰•ã‚¿ã‚¤ãƒ—(デフォルトã¯0期ã®çµ‚ã‚ã‚Š=ã§ã€1期ã®å§‹ã¾ã‚Š=投資)。 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in degrees into radians. "
+msgstr "ラジアンã«åº¦ã®å€¤ã«å¤‰æ›ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the rate at which the given number of payments each invested at the given rate has the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "ã‚’è¿”ã—ã€ã“ã‚Œã§æ”¯æ‰•ã„を指定ã•ã‚ŒãŸæ•°ã”ã¨ã«ã€æŒ‡å®šã•ã‚ŒãŸãƒ¬ãƒ¼ãƒˆã§ã®æŠ•è³‡ã®å‰²åˆã¯ã€ã‚ªãƒ—ションã®å°†æ¥ã®å€¤ï¼ˆãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã¯0)ã¨ãŠæ”¯æ‰•ã„ã®ç¨®é¡žã¨æœŸé–“ã®çµ‚ã‚ã‚Š=ã§ï¼ˆãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã¯0ã€1期ã®å§‹ã¾ã‚Š=)ã¯ã€æŒ‡å®šã•ã‚ŒãŸç¾åœ¨ã®å€¤ã‚’æŒã¡ã¾ã™ã€‚ã¯ã«ï¼ƒNUMã‚’è¿”ã—ã¾ã™ã€‚å復プロセスを使用ã—ã¦ï¼ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ãªã„å ´åˆã¯åŽæŸã™ã‚‹ã€‚ 2ã¤ä»¥ä¸Šå¯èƒ½ãªè§£æ±ºç­–ã«ãªã‚‹ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚特定ã®çŠ¶æ³ã§ã¯ãã‚Œã¯ãªã„åŽæŸã‚’助ã‘ã‚‹ã‹ã‚‚ã—ã‚Œãªã„ã€ã¾ãŸã¯ä¸é©åˆ‡ãªè§£ã‚’求ã‚るオプションã®æŽ¨æ¸¬å€¤ã‚’æä¾›ã™ã‚‹ï¼ˆãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ã¯æŽ¨æ¸¬10%)ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the specified number of characters starting from the specified position replaced by text2. "
+msgstr "文字を指定ã—ãŸä½ç½®ã«ãƒ†ã‚­ã‚¹ãƒˆ2ã«ç½®ãæ›ãˆã‹ã‚‰ã€æŒ‡å®šã—ãŸæ•°ã‚’è¿”ã—ã¾ã™[テキスト1]。 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text repeated the specified number of times. "
+msgstr "テキスト回指定ã—ãŸæ•°ã®ç¹°ã‚Šè¿”ã—ã‚’è¿”ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the end. If count is omitted, 1 is assumed. "
+msgstr "テキストã®å€¤ã®æœ«å°¾ã‹ã‚‰é–‹å§‹ã‹ã‚‰æ–‡å­—ã®æˆ»ã‚Šå€¤ã¯ã€æŒ‡å®šã—ãŸæ•°ã§ã™ã€‚ countã‚’çœç•¥ã™ã‚‹ã¨ã€1ã¨ã¿ãªã•ã‚Œã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value to the specified number of decimal places. If precision is negative, then round to powers of 10. The default precision is 0 (round to integer). "
+msgstr "丸ã‚ã‚‹å°æ•°ç‚¹ä»¥ä¸‹ã®æ¡ã®æŒ‡å®šã•ã‚ŒãŸç•ªå·ã«å€¤ã‚’è¿”ã—ã¾ã™ã€‚å ´åˆã®ç²¾åº¦ãŒè² ã®å ´åˆã€ãã®ãƒ©ã‚¦ãƒ³ãƒ‰ã‚’10ã®ç´¯ä¹—ã™ã‚‹ã€‚デフォルトã®ç²¾åº¦ã¯æ•´æ•°åž‹ã®0(ラウンド)ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of rows in the range. "
+msgstr "ã®ç¯„囲内ã®è¡Œæ•°ã‚’è¿”ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the second portion of a time or date/time value (truncated to an integer). "
+msgstr "時刻ã¾ãŸã¯æ—¥ä»˜ã‚’è¿”ã™ã€2番目ã®éƒ¨åˆ†/時刻ã®å€¤ï¼ˆæ•´æ•°ï¼‰ã«åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric sine function (value is in radians) "
+msgstr "三角法ã®æ­£å¼¦é–¢æ•°ï¼ˆå€¤ã¯ãƒ©ã‚¸ã‚¢ãƒ³ã§ã§ã™ï¼‰ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at each period of time using the straight-line method. "
+msgstr "時間ã®ãã‚Œãžã‚Œã®æœŸé–“ã¯ã€å®šé¡æ³•ã‚’使用ã—ã¦æˆ»ã‚Šå€¤ã®æ¸›ä¾¡å„Ÿå´é¡ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Square root of the value "
+msgstr "値ã®å¹³æ–¹æ ¹ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values. "
+msgstr "数値ã®æˆ»ã‚Šå€¤ã¯ã€ã‚µãƒ³ãƒ—ルã®æ¨™æº–å差を返ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values. "
+msgstr "戻り値ã¯ã€æ•°å€¤å€¤ã®æ¨™æº–å差を返ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the all occurrences of oldtext replaced by newtext. If occurrence is present, then only that occurrence is replaced. "
+msgstr "oldtext newtextã«ç½®ãæ›ãˆã€ã™ã¹ã¦ã®å‡ºç¾ã‚’è¿”ã—ã¾ã™[テキスト1]。もã—発生存在ã™ã‚‹å ´åˆã€ã®ã¿ãŒç½®æ›ã•ã‚Œã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Adds the numeric values. The values to the sum function may be ranges in the form similar to A1:B5. "
+msgstr "数値ã®å€¤ã‚’追加ã—ã¾ã™ã€‚ sum関数ã®å€¤ã¯ã€ãƒ•ã‚©ãƒ¼ãƒ ã®A1ã«åŒæ§˜ã®ç¯„囲:B5ã®å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sums the numeric values of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). If range2 is present, then range1 is tested and the corresponding range2 value is summed. "
+msgstr "範囲内ã®ç·å’Œã®ã‚»ãƒ«ã®æ•°å€¤ãŒåŸºæº–を満ãŸã—ã¦ã„ã¾ã™ã€‚基準値ã§ã‚ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ï¼ˆ'x'ã‚’ã€15ã€1 3)ã€ã¾ãŸã¯ãƒ†ã‚¹ãƒˆï¼ˆ25)。場åˆã€ç¯„囲2ã®å­˜åœ¨ã™ã‚‹å ´åˆã€range1ã€ãƒ†ã‚¹ãƒˆã•ã‚Œã¦ã„る対応ã™ã‚‹ç¯„囲2ã®åˆè¨ˆå€¤ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Depreciation by Sum of Year's Digits method. "
+msgstr "åˆè¨ˆæ–°å¹´ã®æ¡æ³•ã«ã‚ˆã‚‹æ¸›ä¾¡å„Ÿå´è²»ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value or else a null string. "
+msgstr "戻り値ã¯ã€ãƒ†ã‚­ã‚¹ãƒˆå€¤ã€ã¾ãŸã¯ä»–ã®null文字列。 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric tangent function (value is in radians) "
+msgstr "三角関数ã®æ­£æŽ¥é–¢æ•°ï¼ˆå€¤ã¯ãƒ©ã‚¸ã‚¢ãƒ³ã§ã§ã™ï¼‰ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the time value given the specified hour, minute, and second. "
+msgstr "指定ã•ã‚ŒãŸæ™‚é–“ã€åˆ†ã€ãŠã‚ˆã³2番目ã®æŒ‡å®šã•ã‚ŒãŸæ™‚刻を返ã—ã¾ã™å€¤ã‚’è¿”ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date (an integer). Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "戻り値ã¯ã€ç¾åœ¨ã®æ—¥ä»˜ï¼ˆæ•´æ•°ï¼‰ã€‚注:ã“ã®ãƒ—ログラムã§ã¯ã€1日目1899å¹´12月31æ—¥ãŠã‚ˆã³1900å¹´ã¯ã†ã‚‹ã†å¹´ã§ã¯ã‚ã‚Šã¾ã›ã‚“。一部ã®ãƒ—ログラムã¯1900å¹´1月1æ—¥ã€1日目ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ã¨ã€ã†ã‚‹ã†å¹´ã¨ã—ã¦1900扱ã„ã¾ã™ã€‚両方ã®ã‚±ãƒ¼ã‚¹ã§ã¯ã€ã—ã‹ã—ã€ã¾ãŸã¯1900å¹´3月1日以é™ã®æ—¥ä»˜ã¯ã€åŒã˜ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with leading, trailing, and repeated spaces removed. "
+msgstr "リードã—ã¦æˆ»ã‚Šå€¤ã®ãƒ†ã‚­ã‚¹ãƒˆå€¤ã¯ã€æœ«å°¾ã«ã¯ã€ç¹°ã‚Šè¿”ã•ã‚Œã‚‹ã‚¹ãƒšãƒ¼ã‚¹ã‚’削除ã•ã‚Œã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value true. "
+msgstr "戻り値ã¯ã€è«–ç†å€¤ã¯trueã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Truncates the value to the specified number of decimal places. If precision is negative, truncate to powers of 10. "
+msgstr "を切りæ¨ã¦ã¾ã™ã€‚å°æ•°ç‚¹ä»¥ä¸‹ã®æ¡ã®æŒ‡å®šã•ã‚ŒãŸç•ªå·ã«å€¤ã‚’è¿”ã—ã¾ã™ã€‚å ´åˆã®ç²¾åº¦ãŒè² ã®å ´åˆã€10ã®ã¹ã乗を切りæ¨ã¦ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all lowercase characters converted to uppercase. "
+msgstr "ã™ã¹ã¦å°æ–‡å­—ã®æ–‡å­—を大文字ã«å¤‰æ›ã•ã‚ŒãŸãƒ†ã‚­ã‚¹ãƒˆã‚’è¿”ã—ã¾ã™å€¤ã‚’è¿”ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts the specified text value into a numeric value. Various forms that look like numbers (including digits followed by %, forms that look like dates, etc.) are handled. This may not handle all of the forms accepted by other spreadsheets and may be locale dependent. "
+msgstr "数値ã®å€¤ã«æŒ‡å®šã—ãŸãƒ†ã‚­ã‚¹ãƒˆå€¤ã«å¤‰æ›ã—ã¾ã™ã€‚様々ãªå½¢æ…‹ã¯ã€ï¼ˆæ•°å­—ï¼…ã§ç¶šã„ã¦ã€ãƒ•ã‚©ãƒ¼ãƒ ã®æ—¥ä»˜ã®ã‚ˆã†ã«è¦‹ãˆã‚‹ãªã©ï¼‰ã‚’処ç†ã™ã‚‹å ´åˆã‚’å«ã‚€ç•ªå·ã®ã‚ˆã†ã«è¦‹ãˆã‚‹ã€‚ã“ã‚Œã«ã‚ˆã‚Šã€ã™ã¹ã¦ã®ãƒ•ã‚©ãƒ¼ãƒ ã‚’ä»–ã®ã‚¹ãƒ—レッドシートã«ã‚ˆã£ã¦å—ã‘入れ扱ã†ã“ã¨ãŒã§ããªã„ã®ãƒ­ã‚±ãƒ¼ãƒ«ã«ä¾å­˜ã™ã‚‹ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values. "
+msgstr "戻り値ã¯ã€æ•°å€¤ã®å€¤ã¯ã€ã‚µãƒ³ãƒ—ル分散を返ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values. "
+msgstr "戻り値ã¯ã€æ•°å€¤ã®å€¤ã®åˆ†æ•£ã‚’è¿”ã—ã¾ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the column offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match>=value) instead of exact match. "
+msgstr "範囲内ã§æŒ‡å®šã•ã‚ŒãŸå€¤ã¯ã€ä¸€è‡´ã™ã‚‹å€¤ã‚’検索ã—ã¦ã€ã‚»ãƒ«ã®åˆ—ã®ã‚ªãƒ•ã‚»ãƒƒãƒˆã§æŒ‡å®šã•ã‚ŒãŸå¯¾å¿œã™ã‚‹å€¤ã‚’è¿”ã—ã¾ã™ã€‚ã‚‚ã—rangelookup 1(デフォルト)ã¨0ã§ã¯ãªãã€æ•°å€¤ã€æ‹¬å¼§ã®å ´åˆã«ä¸€è‡´ã™ã‚‹ï¼ˆä¸€è‡´= value)ã¨æ­£ç¢ºã«ä¸€è‡´ã™ã‚‹ã®ä»£ã‚ã‚Šã«ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of week specified by the date value. If type is 1 (the default), Sunday is day and Saturday is day 7. If type is 2, Monday is day 1 and Sunday is day 7. If type is 3, Monday is day 0 and Sunday is day 6. "
+msgstr "戻り週ã®æ—¥ä»˜ã®å€¤ã«ã‚ˆã£ã¦æŒ‡å®šã•ã‚ŒãŸæ—¥ã€‚å ´åˆã€ã‚¿ã‚¤ãƒ—1(デフォルト)ã€æ—¥æ›œæ—¥ã€åœŸæ›œæ—¥ã§ã‚ã‚‹7日目ã§ã™ã€‚å ´åˆã€ã‚¿ã‚¤ãƒ—2ã¯ã€æœˆæ›œæ—¥ç¬¬1æ—¥ã¨æ—¥æ›œæ—¥ã®7日目ã§ã™ã€‚å ´åˆã®ã‚¿ã‚¤ãƒ—3ã®å ´åˆã€æœˆæ›œæ—¥day 0ã¨æ—¥æ›œæ—¥ã®6日目ã§ã™ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the year part of a date value. "
+msgstr "戻り値ã®æ—¥ä»˜ã®å€¤ã®å¹´ã®éƒ¨åˆ†ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value"
+msgstr "値"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value1, value2, ..."
+msgstr "ã¯value1ã€value2ã€..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "valueX, valueY"
+msgstr "valueXã€valueY"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "index, value1, value2, ..."
+msgstr "インデックスã¯value1ã€value2ã€..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range"
+msgstr "範囲"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, criteria"
+msgstr "範囲ã€æ¡ä»¶"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "year, month, day"
+msgstr "å¹´ã€æœˆã€æ—¥"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "databaserange, fieldname, criteriarange"
+msgstr "ã€ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰åcriteriarange databaserange"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period [, factor]"
+msgstr "費用ã€æ®‹å­˜ä¾¡é¡ã€å¯¿å‘½æœŸé–“[å› å­]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "string1, string2 [, start]"
+msgstr "string1ãŒã€string2ã®[開始]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [pv, [paytype]]"
+msgstr "レート所蔵ã€ãŠæ”¯æ‰•ã„ã€[PVã€æ­Œè©žã€[paytype]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, row, [rangelookup]"
+msgstr "値ã€ç¯„囲ã€è¡Œã€[rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "logical-expression, true-value, false-value"
+msgstr "è«–ç†å¼ã€çœŸã®å€¤ã‚’ã€å½ã®å€¤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, rownum, colnum"
+msgstr "範囲ã¯ã€rownumã¯ã€colnum"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, [guess]"
+msgstr "範囲ã¯ã€[推測]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, count"
+msgstr "テキストã€ã‚«ã‚¦ãƒ³ãƒˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, base"
+msgstr "値ã¯ã€åŸºæœ¬"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, [rangelookup]"
+msgstr "値ã€ç¯„囲ã€[rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, start, length"
+msgstr "文字列ã€é–‹å§‹ã€é•·ã•"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, payment, pv, [fv, [paytype]]"
+msgstr "料金ã€ãŠæ”¯æ‰•ã„ã€PVã€æ­Œè©žã€[å°†æ¥ä¾¡å€¤ã€[paytype]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, value1, value2, ..."
+msgstr "率ã¯value1ã€value2ã€..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, pv, [fv, [paytype]]"
+msgstr "レート所蔵ã€PVã€æ­Œè©žã€[å°†æ¥ä¾¡å€¤ã€[paytype]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [fv, [paytype]]"
+msgstr "レート所蔵ã€ãŠæ”¯æ‰•ã„ã€[å°†æ¥ä¾¡å€¤ã€[paytype]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "n, payment, pv, [fv, [paytype, [guess]]]"
+msgstr "Ñã€ãŠæ”¯æ‰•ã„ã€PVã€æ­Œè©žã€[å°†æ¥ä¾¡å€¤ã€[paytypeã€[推測]]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, start, length, text2"
+msgstr "[テキスト1]ã‚’èµ·å‹•ã€é•·ã•ã€ãƒ†ã‚­ã‚¹ãƒˆ2"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, [precision]"
+msgstr "値ã¯ã€[高精度]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime"
+msgstr "費用ã€æ®‹å­˜ä¾¡é¡ã€è€ç”¨å¯¿å‘½"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period"
+msgstr "費用ã€æ®‹å­˜ä¾¡é¡ã€å¯¿å‘½æœŸé–“"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, oldtext, newtext [, occurrence]"
+msgstr "[テキスト1]ã€oldtextã€newtext [ã€ç™ºç”Ÿ]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range1, criteria [, range2]"
+msgstr "range1ã€æ¡ä»¶[ã€ç¯„囲2]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "hour, minute, second"
+msgstr "時間ã€åˆ†ã€ç§’"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, col, [rangelookup]"
+msgstr "値ã®ç¯„囲ã¯ã€ã‚«ãƒ©ãƒ ã€[rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date, [type]"
+msgstr "日付ã€[タイプ]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date"
+msgstr "日付"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["all", "stat", "lookup", "datetime", "financial", "test", "math", Text]
+#msgstr ["ã™ã¹ã¦"ã€"åˆè¨ˆ"ã€"検索"ã€"datetime"ã‚’"ã€"金èžã€"テスト"ã€"æ•°å­¦"ã€ãƒ†ã‚­ã‚¹ãƒˆ]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "All"
+msgstr "ã™ã¹ã¦ã®"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Statistics"
+msgstr "統計"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Lookup"
+msgstr "ルックアップ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Date & Time"
+msgstr "日付ã¨æ™‚刻"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Financial"
+msgstr "金èž"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Test"
+msgstr "試験"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Math"
+msgstr "æ•°å­¦"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cells to Graph"
+msgstr "セルグラフã¸"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Graph"
+msgstr "設定ã™ã‚‹ã‚»ãƒ«ã«ã‚°ãƒ©ãƒ•"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph Type"
+msgstr "グラフã®ç¨®é¡ž"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "filter:alpha(opacity=90);opacity:.9;"
+msgstr "フィルタ:アルファ(ä¸é€æ˜Žåº¦= 90);ä¸é€æ˜Žåº¦ï¼š0.9;"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain"
+msgstr "平原"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph"
+msgstr "グラフ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Pie Chart"
+msgstr "円グラフ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Help"
+msgstr "ヘルプ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal Bar"
+msgstr "æ°´å¹³ãƒãƒ¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical Bar"
+msgstr "åž‚ç›´ãƒãƒ¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Line Chart"
+msgstr "線グラフ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plot Points"
+msgstr "プロットãƒã‚¤ãƒ³ãƒˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown range name"
+msgstr "ä¸æ˜Žãªç¯„囲å"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hide Help"
+msgstr "ヘルプを隠ã™"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Max "
+msgstr "マックス "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Min "
+msgstr "分 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " OK "
+msgstr " [OK]ã‚’ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Cancel]"
+msgstr "[キャンセル]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "TRUE"
+msgstr "TRUEã®"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "FALSE"
+msgstr "FALSEã‚’è¿”ã—ã¾ã™"
+
diff --git a/po/pt.po b/po/pt.po
new file mode 100644
index 0000000..bc51497
--- /dev/null
+++ b/po/pt.po
@@ -0,0 +1,1477 @@
+# Copyright (C) 2010 THE PACKAGE"S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# olpc user <olpc@localhost.localdomain>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: SocialCalcActivity.activity\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-01-07 14:46+0000\n"
+"PO-Revision-Date: 2010-01-09 21:53+0530\n"
+"Last-Translator: Diksha<dksh.khatri@gmail.com>\n"
+"Language-Team: Hindi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: activity/activity.info:2
+msgid "SocialCalcActivity"
+msgstr "SocialCalcActivity"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:10
+#msgid "t"
+#msgstr "t"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:13
+msgid "Browser not supported. "
+msgstr "Browser não suportado."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:14
+msgid "Internal SocialCalc error (probably an internal bug):"
+msgstr "Erro interno SocialCalc (provavelmente um erro interno):"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:20
+msgid "Unknown col type item"
+msgstr "Tipo de Item Desconhecido col"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:21
+msgid "Unknown row type item"
+msgstr "Tipo de item de linha Desconhecido"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:22
+msgid "Unknown line type"
+msgstr "Tipo de linha Desconhecido"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:28
+msgid "Unknown cell type item"
+msgstr "Tipo de Item Desconhecido celular"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:36
+msgid "Unknown sheet command: "
+msgstr "Folha de comando desconhecido: "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:37
+msgid "Unknown set coord command: "
+msgstr "Conjunto Unknown comando coord: "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:38
+msgid "Unknown command: "
+msgstr "Comando desconhecido:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:42
+msgid "Circular reference to "
+msgstr "Circular de referência para"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:52
+msgid "padding:2px 2px 1px 2px;vertical-align:top;"
+msgstr "padding: 2px 2px 1px 2px; vertical-align: top;"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:53
+msgid "normal normal"
+msgstr "normal normal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:54
+msgid "small"
+msgstr "pequena"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:55
+msgid "Verdana,Arial,Helvetica,sans-serif"
+msgstr "Arial, Helvetica, sans-serif"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:92
+msgid "Render Context must have a sheet object"
+msgstr "Render Context deve ter um objeto folha"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Executing..."
+msgstr "Execução "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Displaying..."
+msgstr "Resultados ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Ordering..."
+msgstr "Encomendas ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating..."
+msgstr "Calculando ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating... Loading Sheet..."
+msgstr "Calculando ... Carregando folha ..."
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "doing server function "
+msgstr "fazendo a função de servidor"
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " in cell "
+msgstr "na célula"
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculation start..."
+msgstr "Cálculo começar ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SUM"
+msgstr "SOMA"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Multi-line text: Click icon on right to edit]"
+msgstr "[Texto multi-line: Clique no ícone no direito de editar]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function "
+msgstr "Função desconhecida"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane vertically"
+msgstr "Arraste para bloquear painel vertical"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane horizontally"
+msgstr "Arraste para bloquear painel horizontalmente"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Center"
+msgstr "Alinhar ao centro"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Left"
+msgstr "Alinhar à Esquerda"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Right"
+msgstr "Alinhar à Direita"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Alignment"
+msgstr "Alinhamento"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit"
+msgstr "Auditoria"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit Trail This Session"
+msgstr "Audit Trail Esta Sessão"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto"
+msgstr "Auto"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto Sum"
+msgstr "Auto Soma"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto w/ commas"
+msgstr "Auto w / vírgulas"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Automatic"
+msgstr "Automático"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Background"
+msgstr "Fundo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold"
+msgstr "Bold"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold &amp; Italics"
+msgstr "Negrito e itálico"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold Italic"
+msgstr "Bold"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders"
+msgstr "Fronteiras"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders Off"
+msgstr "Fronteiras Off"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders On"
+msgstr "Fronteiras com a"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom"
+msgstr "Fundo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom Border"
+msgstr "Bottom Border"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CELL SETTINGS"
+msgstr "CELULAR CONFIGURAÇÕES"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CSV format"
+msgstr "Formato CSV"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cancel"
+msgstr "Cancelar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Category"
+msgstr "Categoria"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Center"
+msgstr "Centro"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear"
+msgstr "Apagar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear SocialCalc Clipboard"
+msgstr "Limpar SocialCalc Clipboard"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clipboard"
+msgstr "Clipboard"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Color"
+msgstr "Cor"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Column"
+msgstr "Coluna"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Comment"
+msgstr "Comentário"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Copy"
+msgstr "Copiar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Custom"
+msgstr "Prática"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cut"
+msgstr "Cortar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default"
+msgstr "Padrão"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Alignment"
+msgstr "Alinhamento padrão"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Column Width"
+msgstr "Padrão largura da coluna"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Font"
+msgstr "Fonte padrão"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Format"
+msgstr "Formato padrão"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Padding"
+msgstr "Padrão Padding"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete"
+msgstr "Excluir"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Column"
+msgstr "Excluir Coluna"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Contents"
+msgstr "Excluir conteúdo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Row"
+msgstr "Delete Row"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Description"
+msgstr "Descrição"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Display Clipboard in"
+msgstr "Mostrar área de transferência no"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Down"
+msgstr "Abaixo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Edit"
+msgstr "Editar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Existing Names"
+msgstr "Nomes Existentes"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Family"
+msgstr "Familia"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Down"
+msgstr "Fill Down"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Right"
+msgstr "Fill Right"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Font"
+msgstr "Font"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Format"
+msgstr "Formato"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula"
+msgstr "Fórmula"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Function List"
+msgstr "Lista de Funções"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Functions"
+msgstr "Funções"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Grid"
+msgstr "Grid"
+
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hidden"
+msgstr "Hidden"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal"
+msgstr "Horizontal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Column"
+msgstr "Inserir Coluna"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Row"
+msgstr "Insert Row"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Italic"
+msgstr "Itálico"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Last Sort"
+msgstr "Ordenar Última"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left"
+msgstr "Esquerdo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left Border"
+msgstr "Esquerda Fronteiras"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link"
+msgstr "Link"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link Input Box"
+msgstr "Link Caixa de entrada"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "List"
+msgstr "Lista"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Load SocialCalc Clipboard With This"
+msgstr "Load SocialCalc Clipboard With This"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Major Sort"
+msgstr "Ordenar Major"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Manual"
+msgstr "Manual"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Merge Cells"
+msgstr "Unir Células"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Middle"
+msgstr "Médio"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Minor Sort"
+msgstr "Ordenar Menor"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Insert"
+msgstr "Move Inserir"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Paste"
+msgstr "Move Colar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Multi-line Input Box"
+msgstr "Multi-line Caixa de entrada"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Name"
+msgstr "Nome"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Names"
+msgstr "Nomes"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "No padding"
+msgstr "Sem preenchimento"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Normal"
+msgstr "Normal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number"
+msgstr "Number"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number Horizontal"
+msgstr "Número Horizontal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "OK"
+msgstr "OK"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Padding"
+msgstr "Preenchimento"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Page Name"
+msgstr "Nome da Página"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste"
+msgstr "Colar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste Formats"
+msgstr "Colar formatos"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain Text"
+msgstr"Texto Simples"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalc"
+msgstr "Recalcular"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalculation"
+msgstr "Recálculo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " Redo"
+msgstr "Refazer"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right"
+msgstr "Direita"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right Border"
+msgstr "Right Border"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SHEET SETTINGS"
+msgstr "Folha de definições"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save"
+msgstr "Salvar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save to"
+msgstr "Salvar como"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cell Contents"
+msgstr "Definir célula de Conteúdos"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Sort"
+msgstr "Set Células de classificação para"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Value To"
+msgstr "Definir valor para"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set to Link format"
+msgstr "Definir o formato de link para"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set/Clear Move From"
+msgstr "Set / Clear Mova From"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Cell Settings"
+msgstr "Show your Settings"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Sheet Settings"
+msgstr "Show Folha Settings"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show in new browser window"
+msgstr "Show na nova janela do navegador"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Size"
+msgstr "Size"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SocialCalc-save format"
+msgstr "SocialCalc-save format"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort"
+msgstr "Tipo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort Cells"
+msgstr "Células Classificar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Swap Colors"
+msgstr "Swap Colors"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Tab-delimited format"
+msgstr "Formato delimitado por tabulação"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text"
+msgstr "Texto"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text Horizontal"
+msgstr "Texto Horizontal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "This is a<br>sample"
+msgstr "Esta é uma amostra <br>"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top"
+msgstr "Topo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top Border"
+msgstr "Top Border"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "UNDONE STEPS"
+msgstr "UNDONE PASSOS"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "URL"
+msgstr "URL"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Undo"
+msgstr "Undo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unmerge Cells"
+msgstr "Separar as células"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Up"
+msgstr "Para cima"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Value"
+msgstr "Valor"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical"
+msgstr "Vertical"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Workspace"
+msgstr "Workspace"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[New]"
+msgstr "[Novo]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[None]"
+msgstr "[Nenhum]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[select range]"
+msgstr "[intervalo selecione]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
+#msgstr [ "Domingo", "Monday", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
+#msgstr [ "Sun", "Mon", "Ter", "Qua", "Qui", "Sex", "Sáb"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["January", "February", "March", "April", "May", "June", "July", "August", "September","October", "November", "December"]
+#msgstr [ "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "July", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+#msgstr [ "Jan", "Fev", "Mar", "abril", "Maio", "Jun", "Jul", "Aug", "Sep", "Out", "Nov", "Dez"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "AM"
+#msgstr "AM"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "A"
+#msgstr "A"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "PM"
+#msgstr "PM"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "P"
+#msgstr "P"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed number exponent"
+msgstr "Expoente número de formados"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unexpected character in formula"
+msgstr "O personagem inesperado na fórmula"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed string"
+msgstr "O valor formados especial"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed special value"
+msgstr "Valor especial formado inapropiadamente"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula (two operators inappropriately in a row)"
+msgstr "Erro na fórmula (dois operadores inadequadamente em uma linha)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing open parenthesis in list with comma(s)."
+msgstr "Faltando parêntese aberto na lista com vírgula (s)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Closing parenthesis without open parenthesis. "
+msgstr "Fechando parêntese sem parêntese aberto."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing close parenthesis."
+msgstr "Faltando parêntese perto."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing operand."
+msgstr "Faltando operando. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula."
+msgstr "Erro na fórmula."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error value in formula"
+msgstr "O valor de erro na fórmula"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula resulting in bad value"
+msgstr "Erro na fórmula resultante no valor de mau"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in range value:"
+msgstr "Fórmula resultados por faixa de valor:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in an bad numeric value"
+msgstr "Os resultados Formula em um valor numérico ruim"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Numeric overflow"
+msgstr "Estouro numérico"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet unavailable:"
+msgstr "Folha de indisponíveis:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cell reference missing when expected."
+msgstr "Referência de célula em falta quando o esperado."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet name missing when expected."
+msgstr "Nome da folha em falta quando o esperado."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Circular name reference to name"
+msgstr "Referência ao nome Circular nome"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown name"
+msgstr "Nome desconhecido"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Incorrect arguments to function"
+msgstr "Argumentos errados para a função"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function"
+msgstr "Função desconhecida"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LN argument must be greater than 0"
+msgstr "LN argumento deve ser maior que 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG10 argument must be greater than 0"
+msgstr "O argumento LOG10 deve ser maior que 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG second argument must be numeric greater than 0"
+msgstr "LOG segundo argumento deve ser numérico maior que 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG first argument must be greater than 0"
+msgstr "LOG primeiro argumento deve ser maior que 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "ROUND second argument must be numeric"
+msgstr "ROUND segundo argumento deve ser numérico"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "DDB life must be greater than 1"
+msgstr "A vida DDB deve ser superior a 1"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SLN life must be greater than 1"
+msgstr "SLN vida deve ser superior a 1"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Absolute value function. "
+msgstr "Função de valor absoluto."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arccosine function. "
+msgstr "Trigonométricas função cosseno. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if all arguments are true. "
+msgstr "Verdadeiro se todos os argumentos são verdadeiros."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arcsine function. "
+msgstr "Função trigonométrica seno."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arctan function. "
+msgstr "Función trigonometrica arctangente. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arc tangent function (result is in radians). "
+msgstr "Trigonometria função arco tangente resultado (em radianos)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values. "
+msgstr "As médias dos valores."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value specified by the index. The values may be ranges of cells. "
+msgstr "Retorna o valor especificado pelo índice. Os valores podem ser intervalos de células."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of columns in the range. "
+msgstr "Retorna o número de colunas no intervalo."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric cosine function (value is in radians). "
+msgstr "A função trigonométrica cosseno (valor é em radianos)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error. "
+msgstr "Conta o número de valores numéricos, não em branco, texto ou erro."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values. "
+msgstr "Conta o número de valores não-branco."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of blank values. (Note: '' is not blank.) "
+msgstr "Conta o número de valores em branco. (Nota:''não está em branco.)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of number of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). "
+msgstr "Conta o número de número de células no intervalo que satisfazem os critérios. Os critérios podem ser um valor ( 'x', 15, 1 3) ou um teste (> 25)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the appropriate date value given numbers for year, month, and day. For example: DATE(2006,2,1) for February 1, 2006. Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "Retorna o valor de data apropriado, dado os números para o ano, mês e dia. Por exemplo: DATA (2006,2,1) para 1 de fevereiro de 2006. Nota: Neste programa, dia 1 é 31 de dezembro de 1899 eo ano 1900 não é um ano bissexto. Alguns programas usam 1 de janeiro de 1900, no dia 1 e tratar a 1900 como um ano bissexto. Em ambos os casos, porém, as datas em ou após 1 de março de 1900, são os mesmos. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values in the specified field in records that meet the criteria. "
+msgstr "As médias dos valores no campo especificado nos registros que atendem aos critérios."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of month for a date value. "
+msgstr "Retorna o dia do mês para um valor de data."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error, in the specified field in records that meet the criteria. "
+msgstr "Conta o número de valores numéricos, não em branco, texto ou erro, no campo especificado nos registros que atendem aos critérios."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values in the specified field in records that meet the criteria. "
+msgstr "Conta o número de valores não-branco no campo especificado em registros que atendem aos critérios."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at the given period of time (the default factor is 2 for double-declining balance). "
+msgstr "Retorna o valor da depreciação no período determinado de tempo (o fator padrão é 2 de declínio duplo equilíbrio)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in radians into degrees. "
+msgstr "Converte o valor em radianos em graus."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value of the specified field in the single record that meets the criteria. "
+msgstr "Retorna o valor do campo especificado no registro único que atende aos critérios."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Retorna o máximo dos valores numéricos no campo especificado nos registros que atendem aos critérios."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values in the specified field in records that meet the criteria. "
+msgstr "Retorna o resultado da multiplicação dos valores numéricos no campo especificado em registros que atendem aos critérios."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Retorna o desvio padrão da amostra dos valores numéricos no campo especificado nos registros que atendem aos critérios."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Retorna o desvio padrão dos valores numéricos no campo especificado nos registros que atendem aos critérios."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sum of the numeric values in the specified field in records that meet the criteria. "
+msgstr"Retorna a soma dos valores numéricos no campo especificado em registros que atendem aos critérios."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Retorna a variância amostral dos valores numéricos no campo especificado nos registros que atendem aos critérios."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Retorna a variância dos valores numéricos no campo especificado em registros que atendem aos critérios."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest even integer. "
+msgstr "Arredonda o valor em magnitude para o mais próximo inteiro."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the values are exactly the same, including case, type, etc. "
+msgstr "Retorna true se os valores são exactamente os mesmos, incluindo o caso, tipo, etc"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns e raised to the value power. "
+msgstr"Retorna e elevado à potência de valor."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns factorial of the value. "
+msgstr "Retorna o fatorial do valor."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value false. "
+msgstr "Retorna o valor lógico falso."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the starting position within string2 of the first occurrence of string1 at or after start. If start is omitted, 1 is assumed. "
+msgstr"Retorna a posição inicial em string2 da primeira ocorrência da string1 durante ou após a partida. Se start for omitido, 1 será adotado."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the future value of repeated payments of money invested at the given rate for the specified number of periods, with optional present value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Retorna o valor futuro dos pagamentos repetidos de dinheiro investido à taxa dada para o número especificado de períodos, com o valor actual opcional (padrão 0) e tipo de pagamento (default = 0 no final do período, 1 = início do período)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the row offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. "
+msgstr "Olhe para o valor correspondente para o valor dado no intervalo e retornar o valor correspondente na célula especificada pela linha offset. Rangelookup Se é 1 (o padrão) e não 0, partida se entre parênteses numérico (match <= valor) em vez de correspondência exata. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the hour portion of a time or date/time value. "
+msgstr "Retorna a hora de uma porção de tempo ou valor de data / hora."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Results in true-value if logical-expression is TRUE or non-zero, otherwise results in false-value. "
+msgstr "Os resultados em valor verdadeiro se lógico-expressão é verdadeira ou não-zero, caso contrário, resulta em valor falso."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns a cell or range reference for the specified row and column in the range. If range is 1-dimensional, then only one of rownum or colnum are needed. If range is 2-dimensional and rownum or colnum are zero, a reference to the range of just the specified column or row is returned. You can use the returned reference value in a range, e.g., sum(A1:INDEX(A2:A10,4)). "
+msgstr "Regresa una celda o una referencia de rango para la fila y columna especificada en el rango. Si el rango es 1-dimensional, entonces unicamente se necesita una de las filanúmero o columnanúmero. Si el rango es 2-dimensional y la filanúmero o columnanúmero son cero, una referencia del rango de solo la columna o fila especificada es regresada. Usted puede usar el valor de la referencia regresada en un rango, ejemplo, sum(A1:INDEX(A2:A10,4)). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value rounded down to the nearest integer (towards -infinity). "
+msgstr "Retorna o valor arredondado para o número inteiro mais próximo (em direcção-infinito)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the interest rate at which the cash flows in the range have a net present value of zero. Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "Retorna a taxa de juro a que os fluxos de caixa no intervalo tem um valor actual líquido de zero. Utiliza um processo iterativo que irá devolver o erro # NUM! Se não convergir. Pode haver mais de uma solução possível. Proporcionar o opcional valor acho que pode ajudar em certas situações em que não converge, ou encontrar uma solução inadequada (acho que o padrão é de 10%). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is a reference to a blank cell. "
+msgstr "Retorna true se o valor for uma referência a uma célula em branco."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error but not NA. "
+msgstr "Retorna true se o valor é de erro de tipo, mas não de NA."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error. "
+msgstr "Retorna true se o valor é do tipo de erro."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Logical (true/false). "
+msgstr "Retorna true se o valor é do tipo lógico (verdadeiro / falso)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is the error type NA. "
+msgstr "Retorna true se o valor é o erro de tipo NA."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is not of type Text. "
+msgstr "Retorna true se o valor não é do tipo Texto."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Number (including logical values). "
+msgstr "Retorna true se o valor é do tipo Number (incluindo os valores lógicos)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Text. "
+msgstr "Retorna true se o valor for do tipo Texto."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value. If count is omitted, 1 is assumed. "
+msgstr "Retorna o número especificado de caracteres do valor de texto. Se a contagem for omitido, 1 será adotado."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of characters in the text value. "
+msgstr "Devolve o número de caracteres no valor de texto."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the natural logarithm of the value. "
+msgstr "Retorna o logaritmo do valor usando a base especificado."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logarithm of the value using the specified base. "
+msgstr "Regresa el logritmo del valor usando la base especificada. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the base 10 logarithm of the value. "
+msgstr "Devolve o logaritmo base 10 do valor."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all uppercase characters converted to lowercase. "
+msgstr "Retorna o valor de texto com todas as letras maiúsculas convertidas em minúsculas."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return position (the first is 1) in that range. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. If rangelookup is -1, act like 1 but the bracket is match>=value. "
+msgstr "Olhe para o valor correspondente para o valor dado no intervalo ea posição de retorno (o primeiro é 1) nesse intervalo. Rangelookup Se é 1 (o padrão) e não 0, partida se entre parênteses numérico (match <= valor) em vez de correspondência exata. Se rangelookup é -1, agem como 1, mas o suporte é match> = valor. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values. "
+msgstr "Retorna o máximo dos valores numéricos."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the specified position. "
+msgstr "Retorna o número especificado de caracteres do valor de texto a partir da posição especificada."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minimum of the numeric values. "
+msgstr "Devolve o mínimo dos valores numéricos."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minute portion of a time or date/time value. "
+msgstr "Retorna a porção de um minuto de tempo ou valor de data / hora."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the remainder of the first value divided by the second. "
+msgstr "Retorna o resto do primeiro valor dividido pelo segundo."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the month part of a date value. "
+msgstr "Retorna a parte do mês de um valor de data."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value if it is a numeric value otherwise an error. "
+msgstr "Retorna o valor se for um valor numérico em contrário é um erro."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the #N/A error value which propagates through most operations. "
+msgstr"Retorna # N / A valor de erro que se propaga para a maioria das operações."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns FALSE if value is true, and TRUE if it is false. "
+msgstr "Retorna FALSE se o valor for verdadeiro, e verdadeiras Se isto é falso."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date/time. "
+msgstr "Retorna a data / hora atual."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of periods at which payments invested each period at the given rate with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period) has the given present value. "
+msgstr "Retorna o número de períodos em que os pagamentos investido cada período, a taxa de dados com valor futuro opcional (padrão 0) e tipo de pagamento (default = 0 no final do período, 1 = início do período) tem o valor dado presente."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the net present value of cash flows (which may be individual values and/or ranges) at the given rate. The flows are positive if income, negative if paid out, and are assumed at the end of each period. "
+msgstr "Retorna o valor presente líquido dos fluxos de caixa (que podem ser valores individuais e / ou intervalos) com a taxa determinada. Os fluxos são positivos, se o rendimento negativo, se paga, e são assumidas no final de cada período."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest odd integer. "
+msgstr "Arredonda o valor em magnitude para o próximo número ímpar."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if any argument is true "
+msgstr "True se qualquer argumento é verdadeiro"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "The value 3.1415926... "
+msgstr "O valor 3.1415926 ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of each payment that must be invested at the given rate for the specified number of periods to have the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Retorna o valor de cada pagamento, que deve ser investido a uma taxa dada para o número especificado de períodos para ter o valor especificado presente, com o valor futuro opcional (padrão 0) e tipo de pagamento (default = 0 no final do período, 1 = início do período). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the first value raised to the second value power. "
+msgstr"Retorna o primeiro valor elevado à potência segundo valor."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values. "
+msgstr "Retorna o resultado da multiplicação dos valores numéricos."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with the first letter of each word converted to uppercase and the others to lowercase. "
+msgstr "Retorna o valor de texto com a primeira letra de cada palavra convertida para maiúscula e as demais em minúsculas."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the present value of the given number of payments each invested at the given rate, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Retorna o valor presente de um dado número de pagamentos a cada investida à taxa determinada, com valor futuro opcional (padrão 0) e tipo de pagamento (default = 0 no final do período, 1 = início do período)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in degrees into radians. "
+msgstr "Converte o valor em graus para radianos."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the rate at which the given number of payments each invested at the given rate has the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "Retorna a taxa na qual um dado número de pagamentos a cada investida à taxa de dado tem o valor especificado presente, com o valor futuro opcional (padrão 0) e tipo de pagamento (default = 0 no final do período, 1 = início do período). utiliza um processo iterativo, que irá retornar o erro # NUM! se não convergir. Pode haver mais de uma solução possível. fornecer o valor acho opcionais podem ajudar em certas situações em que não converge, ou encontrar uma solução inadequada (o padrão adivinhar é de 10%). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the specified number of characters starting from the specified position replaced by text2. "
+msgstr "Retorna text1 com o número especificado de caracteres a partir da posição especificada substituído por texto2."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text repeated the specified number of times. "
+msgstr "Retorna o texto repetido o número de vezes especificado."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the end. If count is omitted, 1 is assumed. "
+msgstr "Retorna o número especificado de caracteres do valor de texto a partir do final. Se a contagem for omitido, 1 será adotado."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value to the specified number of decimal places. If precision is negative, then round to powers of 10. The default precision is 0 (round to integer). "
+msgstr "Arredonda o valor para o número especificado de casas decimais. Se a precisão for negativa, então volta para potências de 10. A precisão padrão é 0 (arredondar para número inteiro)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of rows in the range. "
+msgstr "Retorna o número de linhas no intervalo."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the second portion of a time or date/time value (truncated to an integer). "
+msgstr "Retorna a segunda parcela de um tempo ou valor de data / hora (truncado para um inteiro)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric sine function (value is in radians) "
+msgstr "Função trigonométrica seno (valor é em radianos)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at each period of time using the straight-line method. "
+msgstr "Retorna o valor da depreciação em cada período de tempo usando o método da linha recta."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Square root of the value "
+msgstr "Raiz quadrada do valor"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values. "
+msgstr "Retorna o desvio padrão da amostra dos valores numéricos."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values. "
+msgstr "Retorna o desvio padrão dos valores numéricos."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the all occurrences of oldtext replaced by newtext. If occurrence is present, then only that occurrence is replaced. "
+msgstr "Retorna text1 com as ocorrências de todos oldtext substituído por newtext. Ocorrência Se estiver presente, então, apenas que a ocorrência é substituído."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Adds the numeric values. The values to the sum function may be ranges in the form similar to A1:B5. "
+msgstr "Adiciona los valores numéricos. Los valores para la función suma pueden ser rangos en la forma similar a A1:B5. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sums the numeric values of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). If range2 is present, then range1 is tested and the corresponding range2 value is summed. "
+msgstr "Soma os valores numéricos das células no intervalo que satisfazem os critérios. Os critérios podem ser um valor ( 'x', 15, 1 3) ou um teste (> 25). Range2 Se estiver presente, então range1 é testado e range2 o valor correspondente é somada. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Depreciation by Sum of Year's Digits method. "
+msgstr "Depreciação pelo método de Soma de Dígitos do Ano."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value or else a null string. "
+msgstr "Retorna o valor de texto ou então uma seqüência de caracteres nula."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric tangent function (value is in radians) "
+msgstr "A função trigonométrica tangente (valor é em radianos)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the time value given the specified hour, minute, and second. "
+msgstr "Retorna o valor do tempo, dada a hora especificada, minuto e segundo."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date (an integer). Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "Retorna a data atual (um inteiro). Nota: Neste programa, dia 1 é 31 de dezembro de 1899 e no ano 1900 não é um ano bissexto. Alguns programas usam 1 de janeiro de 1900, no dia 1 e tratar a 1900, como um salto ano. Em ambos os casos, porém, as datas em ou após 1 de março de 1900, são os mesmos. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with leading, trailing, and repeated spaces removed. "
+msgstr "Retorna o valor do texto principal, à direita, e os espaços repetidos removido."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value true. "
+msgstr "Retorna o valor lógico verdadeiro."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Truncates the value to the specified number of decimal places. If precision is negative, truncate to powers of 10. "
+msgstr "Trunca o valor para o número especificado de casas decimais. Se a precisão for negativo, truncar à potências de 10."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all lowercase characters converted to uppercase. "
+msgstr "Retorna o valor de texto com todos os caracteres em minúsculas convertidas para maiúsculas."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts the specified text value into a numeric value. Various forms that look like numbers (including digits followed by %, forms that look like dates, etc.) are handled. This may not handle all of the forms accepted by other spreadsheets and may be locale dependent. "
+msgstr "Converte o valor de texto especificado em um valor numérico. Várias formas que se parecem com números (incluindo os números seguidos%, as formas que se parecem com datas, etc) são tratados. Este não pode lidar com todas as formas aceitas por outras planilhas e pode ser dependente da localidade. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values. "
+msgstr "Retorna a variância amostral dos valores numéricos."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values. "
+msgstr "Retorna a variância dos valores numéricos."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the column offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match>=value) instead of exact match. "
+msgstr "Olhe para o valor correspondente para o valor dado no intervalo e retornar o valor correspondente na célula especificada pela coluna offset. Rangelookup Se é 1 (o padrão) e não 0, partida se entre parênteses numérico (match> = valor) em vez de correspondência exata. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of week specified by the date value. If type is 1 (the default), Sunday is day and Saturday is day 7. If type is 2, Monday is day 1 and Sunday is day 7. If type is 3, Monday is day 0 and Sunday is day 6. "
+msgstr "Retorna o dia da semana especificado pelo valor de data. Se o tipo é 1 (o padrão), Domingo é dia de feira e sábado é dia 7. Se é tipo 2, segunda-feira é dia 1 e domingo é dia 7. Se é tipo 3, Segunda-feira é dia 0 e no domingo é dia 6. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the year part of a date value. "
+msgstr "Retorna a parte do ano de um valor de data."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value"
+msgstr "valor"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value1, value2, ..."
+msgstr "valor1, valor2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "valueX, valueY"
+msgstr "valorX, valorY"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "index, value1, value2, ..."
+msgstr "indice, valor1, valor2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range"
+msgstr "intervalo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, criteria"
+msgstr "intervalo, critérios"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "year, month, day"
+msgstr "No ano, mês, dia"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "databaserange, fieldname, criteriarange"
+msgstr "databaserange, fieldname, CriteriaRange"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period [, factor]"
+msgstr "custo, recuperação, tempo de vida, período, [factor]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "string1, string2 [, start]"
+msgstr "string1, string2 [start,]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [pv, [paytype]]"
+msgstr "tasa, n, pago, [pv, [tipopago]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, row, [rangelookup]"
+msgstr "O valor, escala, linha [rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "logical-expression, true-value, false-value"
+msgstr "A expressão-lógica, o valor verdadeiro, falso-valor"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, rownum, colnum"
+msgstr "intervalo, rownum, colnum"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, [guess]"
+msgstr "range, [acho]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, count"
+msgstr "O texto, contar"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, base"
+msgstr "valor, base"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, [rangelookup]"
+msgstr "valor, intervalo , [rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, start, length"
+msgstr "texto, de início, duração"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, payment, pv, [fv, [paytype]]"
+msgstr "taxa, taxa, pv,[FV, [PayType]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, value1, value2, ..."
+msgstr "taxa, valor1, valor2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, pv, [fv, [paytype]]"
+msgstr "taxa, n, pv, [fv, [PayType]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [fv, [paytype]]"
+msgstr "taxa, n, pagamento, [fv, [PayType]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "n, payment, pv, [fv, [paytype, [guess]]]"
+msgstr "n, pagamento, pv, [fv, [PayType, [suponer]]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, start, length, text2"
+msgstr "texto1, start, length, texto2"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, [precision]"
+msgstr "valor, [precisão]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime"
+msgstr "custo, recuperação, tempo de vida"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period"
+msgstr "custo, recuperação, tempo de vida, período"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, oldtext, newtext [, occurrence]"
+msgstr "text1, oldtext, newtext, [ocorrência]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range1, criteria [, range2]"
+msgstr "range1, critérios, [range2]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "hour, minute, second"
+msgstr "hora, minuto, segundo"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, col, [rangelookup]"
+msgstr "O valor, alcance, col, [rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date, [type]"
+msgstr "data [tipo]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date"
+msgstr "date"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["all", "stat", "lookup", "datetime", "financial", "test", "math", Text]
+#msgstr [ "todos", "stat", "pesquisa", "datetime", "Financeiro", "teste", "matemática", Texto]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "All"
+msgstr "Todos"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Statistics"
+msgstr "Estadisticas"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Lookup"
+msgstr "Page"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Date & Time"
+msgstr "Data & Hora"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Financial"
+msgstr "Financeiro"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Test"
+msgstr "Test"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Math"
+msgstr "Matemática"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cells to Graph"
+msgstr "Células a Graph"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Graph"
+msgstr "Para Definir Células Gráfico"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph Type"
+msgstr "Tipo de Gráfico"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "filter:alpha(opacity=90);opacity:.9;"
+msgstr "filter: alpha (opacity = 90); opacity: .9;"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain"
+msgstr "Plain"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph"
+msgstr "Gráfico"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Pie Chart"
+msgstr "Pie Chart"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Help"
+msgstr "Ajuda"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal Bar"
+msgstr "barra horizontal"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical Bar"
+msgstr "Vertical Barra"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Line Chart"
+msgstr "Gráfico de linhas"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plot Points"
+msgstr "Pontos do lote"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown range name"
+msgstr "Nome de intervalo desconhecido"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hide Help"
+msgstr "ocultar Ajuda"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Max "
+msgstr "Max "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Min "
+msgstr "Min "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " OK "
+msgstr " OK "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Cancel]"
+msgstr "[Cancelar]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "TRUE"
+msgstr "TRUE"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "FALSE"
+msgstr "FALSE"
+
diff --git a/po/ru.po b/po/ru.po
new file mode 100644
index 0000000..e0dfbc1
--- /dev/null
+++ b/po/ru.po
@@ -0,0 +1,1474 @@
+# Copyright (C) 2010 THE PACKAGE"S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# olpc user <olpc@localhost.localdomain>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: SocialCalcActivity.activity\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-01-07 14:46+0000\n"
+"PO-Revision-Date: 2010-01-09 21:53+0530\n"
+"Last-Translator: Diksha<dksh.khatri@gmail.com>\n"
+"Language-Team: Hindi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: activity/activity.info:2
+msgid "SocialCalcActivity"
+msgstr "SocialCalcActivity"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:10
+#msgid "t"
+#msgstr "Т"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:13
+msgid "Browser not supported. "
+msgstr "Браузер не поддерживаетÑÑ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:14
+msgid "Internal SocialCalc error (probably an internal bug):"
+msgstr "SocialCalc ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° (возможно, внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°):"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:20
+msgid "Unknown col type item"
+msgstr "ÐеизвеÑтный тип Ñлемента Col"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:21
+msgid "Unknown row type item"
+msgstr "ÐеизвеÑтный тип Ñлемента Ñтроки"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:22
+msgid "Unknown line type"
+msgstr "ÐеизвеÑтный тип линии"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:28
+msgid "Unknown cell type item"
+msgstr "ÐеизвеÑтный тип Ñлемента Cell"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:36
+msgid "Unknown sheet command: "
+msgstr "ÐеизвеÑÑ‚Ð½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° лиÑте: "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:37
+msgid "Unknown set coord command: "
+msgstr "Coord ÐеизвеÑÑ‚Ð½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°: "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:38
+msgid "Unknown command: "
+msgstr "ÐеизвеÑÑ‚Ð½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°: "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:42
+msgid "Circular reference to "
+msgstr "ЦиркулÑÑ€ ÑÑылкой на "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:52
+msgid "padding:2px 2px 1px 2px;vertical-align:top;"
+msgstr "PADDING: 2px 2px 1px 2px; вертикальной Align: Top;"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:53
+msgid "normal normal"
+msgstr "ÐÐ¾Ñ€Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ ÐормальнаÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:54
+msgid "small"
+msgstr "маленький"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:55
+msgid "Verdana,Arial,Helvetica,sans-serif"
+msgstr "Verdana, Arial, Helvetica, без заÑечек"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:92
+msgid "Render Context must have a sheet object"
+msgstr "Render контекÑте должна иметь лиÑÑ‚ объект"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Executing..."
+msgstr "Выполнение ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Displaying..."
+msgstr "ПроÑмотр ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Ordering..."
+msgstr "Заказ ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating..."
+msgstr "РаÑчет ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating... Loading Sheet..."
+msgstr "РаÑчет ... Загрузка лиÑта ..."
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "doing server function "
+msgstr "делать функции Ñервера "
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " in cell "
+msgstr "в Ñчейке "
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculation start..."
+msgstr "Ðачало раÑчета ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SUM"
+msgstr "СГМ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Multi-line text: Click icon on right to edit]"
+msgstr "[Multi-лайн текÑÑ‚: Ðажмите на иконку на право править]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function "
+msgstr "ÐеизвеÑÑ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane vertically"
+msgstr "Перетащите Ð´Ð»Ñ Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²ÐºÐ¸ панели вертикальным"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane horizontally"
+msgstr "Перетащите Ð´Ð»Ñ Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²ÐºÐ¸ панели горизонтального"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Center"
+msgstr "ВыровнÑÑ‚ÑŒ по центру"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Left"
+msgstr "По левому краю"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Right"
+msgstr "По правому краю"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Alignment"
+msgstr "Выравнивание"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit"
+msgstr "Ðудит"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit Trail This Session"
+msgstr "Audit Trail Эта ÑеÑÑиÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto"
+msgstr "Ðвто"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto Sum"
+msgstr "Ðвто Sum"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto w/ commas"
+msgstr "Ðвто без запÑÑ‚Ñ‹Ñ…"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Automatic"
+msgstr "ÐвтоматичеÑкаÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Background"
+msgstr "Фон"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold"
+msgstr "Жирный"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold &amp; Italics"
+msgstr "Жирный КурÑив &"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold Italic"
+msgstr "Жирный КурÑив"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders"
+msgstr "Границы"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders Off"
+msgstr "Границы Off"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders On"
+msgstr "Граничит"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom"
+msgstr "Дно"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom Border"
+msgstr "ÐижнÑÑ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ð°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CELL SETTINGS"
+msgstr "КЛЕТОК ÐÐСТРОЙКИ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CSV format"
+msgstr "CSV формат"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cancel"
+msgstr "Отмена"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Category"
+msgstr "Категории"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Center"
+msgstr "Центр"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear"
+msgstr "ЯÑный"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear SocialCalc Clipboard"
+msgstr "Открытый SocialCalc буфер обмена"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clipboard"
+msgstr "Буфер обмена"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Color"
+msgstr "Цвет"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Column"
+msgstr "Колонка"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Comment"
+msgstr "Комментарии"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Copy"
+msgstr "Копировать"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Custom"
+msgstr "Обычай"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cut"
+msgstr "Резать"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default"
+msgstr "По умолчанию"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Alignment"
+msgstr "Выравнивание по умолчанию"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Column Width"
+msgstr "По умолчанию ширину Ñтолбца"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Font"
+msgstr "Шрифт по умолчанию"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Format"
+msgstr "Формат по умолчанию"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Padding"
+msgstr "Умолчанию заполнÑÑŽÑ‚ÑÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete"
+msgstr "Удалить"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Column"
+msgstr "Удалить Ñтолбец"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Contents"
+msgstr "Удалить Ñодержимое"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Row"
+msgstr "Удалить Ñтроку"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Description"
+msgstr "ОпиÑание"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Display Clipboard in"
+msgstr "ДиÑплей в буфер обмена"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Down"
+msgstr "Вниз"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Edit"
+msgstr "Изменить"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Existing Names"
+msgstr "СущеÑтвующих названий"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Family"
+msgstr "СемьÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Down"
+msgstr "Заполнить вниз"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Right"
+msgstr "Заполните Право"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Font"
+msgstr "Шрифта"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Format"
+msgstr "Формат"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula"
+msgstr "Формулы"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Function List"
+msgstr "СпиÑок функций"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Functions"
+msgstr "Функции"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Grid"
+msgstr "Grid"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hidden"
+msgstr "Скрытые"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal"
+msgstr "ГоризонтальнаÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Column"
+msgstr "Ð’Ñтавить колонку"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Row"
+msgstr "Ð’Ñтавить Ñтроку"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Italic"
+msgstr "КурÑив"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Last Sort"
+msgstr "Сортировка"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left"
+msgstr "Левый"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left Border"
+msgstr "Ð›ÐµÐ²Ð°Ñ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ð°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link"
+msgstr "СÑылка"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Link Input Box"
+msgstr "СÑылка Input Box"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "List"
+msgstr "СпиÑок"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Load SocialCalc Clipboard With This"
+msgstr "Ðагрузка SocialCalc Это буфер обмена"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Major Sort"
+msgstr "ОÑновной Сортировка"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Manual"
+msgstr "РуководÑтва"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Merge Cells"
+msgstr "Объединить Ñчейки"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Middle"
+msgstr "Ближний"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Minor Sort"
+msgstr "Малые Сортировка"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Insert"
+msgstr "ПеремеÑтить Включить"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Paste"
+msgstr "ПеремеÑтить Ð’Ñтавить"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Multi-line Input Box"
+msgstr "Multi-Line Input Box"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Name"
+msgstr "ИмÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Names"
+msgstr "Ðазвание"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "No padding"
+msgstr "Ðет обивка"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Normal"
+msgstr "ÐормальнаÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number"
+msgstr "Ðомер"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number Horizontal"
+msgstr "Ðомер ГоризонтальнаÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "OK"
+msgstr "OK"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Padding"
+msgstr "Прокладки"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Page Name"
+msgstr "Ð˜Ð¼Ñ Ñтраницы"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste"
+msgstr "Ð’Ñтавить"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste Formats"
+msgstr "Ð’Ñтавить форматы"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain Text"
+msgstr "Plain Text"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalc"
+msgstr "ПереÑчет"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalculation"
+msgstr "ПереÑчет"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " Redo"
+msgstr " Повтор"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right"
+msgstr "Правый"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right Border"
+msgstr "ÐŸÑ€Ð°Ð²Ð°Ñ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ð°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SHEET SETTINGS"
+msgstr "СПРÐВКРÐÐСТРОЙКИ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save"
+msgstr "Сохранить"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save to"
+msgstr "Сохранить"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cell Contents"
+msgstr "УÑтановить Ñодержимое Ñчейки"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Sort"
+msgstr "Задать Сортировка клеток"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Value To"
+msgstr "Задание Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set to Link format"
+msgstr "УÑтановить Ð´Ð»Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð° ÑÑылки"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set/Clear Move From"
+msgstr "УÑтановить / ОчиÑтить перейти от"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Cell Settings"
+msgstr "Показать наÑтройки Cell"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Sheet Settings"
+msgstr "Показать наÑтройки лиÑта"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show in new browser window"
+msgstr "Показать в новом окне браузера"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Size"
+msgstr "Размер"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SocialCalc-save format"
+msgstr "SocialCalc-Ñохранить формат"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort"
+msgstr "Сортировка"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort Cells"
+msgstr "Сортировать Cells"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Swap Colors"
+msgstr "Swap цвета"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Tab-delimited format"
+msgstr "РазделителÑми табулÑции формат"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text"
+msgstr "ТекÑÑ‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text Horizontal"
+msgstr "ТекÑÑ‚ ГоризонтальнаÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "This is a<br>sample"
+msgstr "Это<br>пример"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top"
+msgstr "Верх"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top Border"
+msgstr "ВерхнÑÑ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ð°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "UNDONE STEPS"
+msgstr "Undone ШÐГИ"
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "URL"
+msgstr "URL"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Undo"
+msgstr "Отменить"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unmerge Cells"
+msgstr "Unmerge Cells"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Up"
+msgstr "Вверх"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Value"
+msgstr "Соотношение"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical"
+msgstr "Вертикальные"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Workspace"
+msgstr "Ð Ð°Ð±Ð¾Ñ‡Ð°Ñ Ð¾Ð±Ð»Ð°ÑÑ‚ÑŒ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[New]"
+msgstr "[Ðовый]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[None]"
+msgstr "[ОтÑутÑтвует]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[select range]"
+msgstr "[выберите диапазон]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
+#msgstr ["ВоÑкреÑенье", "Понедельник", "Вторник", "Среда", "Четверг", "ПÑтница", "Суббота"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
+#msgstr [ "ВС", "Mon", "ВТ", "Ср", "Чт", "ПТ", "СБ"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["January", "February", "March", "April", "May", "June", "July", "August", "September","October", "November", "December"]
+#msgstr [ "Январь", "Февраль", "Март", "Ðпрель", "Май", "Июнь", "Июль", "ÐвгуÑÑ‚", "СентÑбрь", "ОктÑбрь", "ÐоÑбрь", "Декабрь"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+#msgstr [ "Янв", "Фев", "Мар", "Ðпр", "Май", "Июнь", "Июл", "Ðвг", "Сен", "Окт", "ÐоÑ", "Дек"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "AM"
+#msgstr "AM"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "A"
+#msgstr "A"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "PM"
+#msgstr "PM"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "P"
+#msgstr "П"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed number exponent"
+msgstr "Ðеправильную форму чиÑла показателÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unexpected character in formula"
+msgstr "Ðеожиданный Ñимвол в формуле"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed string"
+msgstr "Ðеправильно Ñформированные Ñтроки"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed special value"
+msgstr "Ðеправильную форму Ñпециального значениÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula (two operators inappropriately in a row)"
+msgstr "Ошибка в формуле (два оператора неправильным в Ñтроке)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing open parenthesis in list with comma(s)."
+msgstr "ОтÑутÑтвие открытой Ñкобкой в ÑпиÑке через запÑтую (Ñ‹)."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Closing parenthesis without open parenthesis. "
+msgstr "Ð—Ð°ÐºÑ€Ñ‹Ð²Ð°ÑŽÑ‰Ð°Ñ Ñкобка без открытой Ñкобкой. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing close parenthesis."
+msgstr "ОтÑутÑтвует теÑное Ñкобках."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing operand."
+msgstr "ОтÑутÑтвует операнд."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula."
+msgstr "Ошибка в формуле."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error value in formula"
+msgstr "Значение ошибки в формуле"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula resulting in bad value"
+msgstr "Ошибка в формуле в результате плохой значениÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in range value:"
+msgstr "Формулы результатов в диапазоне значений:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in an bad numeric value"
+msgstr "Формулы результатов в плохой чиÑловые значениÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Numeric overflow"
+msgstr "Ð¦Ð¸Ñ„Ñ€Ð¾Ð²Ð°Ñ Ð¿ÐµÑ€ÐµÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ðµ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet unavailable:"
+msgstr "ЛиÑÑ‚ недоÑтупны:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cell reference missing when expected."
+msgstr "СÑылка на Ñчейку хватает, когда ожидаетÑÑ."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet name missing when expected."
+msgstr "ЛиÑÑ‚ отÑутÑтвует имÑ, когда ожидаетÑÑ."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Circular name reference to name"
+msgstr "ЦиркулÑÑ€ Ð¸Ð¼Ñ ÑÑылки на имÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown name"
+msgstr "ÐеизвеÑтное название"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Incorrect arguments to function"
+msgstr "Ðеправильные аргументы функции"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function"
+msgstr "ÐеизвеÑÑ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LN argument must be greater than 0"
+msgstr "Л. Ð. аргумент должен быть больше 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG10 argument must be greater than 0"
+msgstr "LOG10 аргумент должен быть больше 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG second argument must be numeric greater than 0"
+msgstr "ВХОД второй аргумент должен быть больше, чем чиÑловые 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG first argument must be greater than 0"
+msgstr "ВХОД Первый аргумент должен быть больше 0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "ROUND second argument must be numeric"
+msgstr "КРУГЛЫЙ второй аргумент должен быть чиÑловым"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "DDB life must be greater than 1"
+msgstr "DDB жизни должно быть больше 1"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SLN life must be greater than 1"
+msgstr "SLN жизни должно быть больше 1"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Absolute value function. "
+msgstr "ÐбÑолютные Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arccosine function. "
+msgstr "ÐрккоÑÐ¸Ð½ÑƒÑ Ñ‚Ñ€Ð¸Ð³Ð¾Ð½Ð¾Ð¼ÐµÑ‚Ñ€Ð¸Ñ‡ÐµÑкие функции. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if all arguments are true. "
+msgstr "Правда, еÑли вÑе аргументы иÑтинны. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arcsine function. "
+msgstr "ÐркÑÐ¸Ð½ÑƒÑ Ñ‚Ñ€Ð¸Ð³Ð¾Ð½Ð¾Ð¼ÐµÑ‚Ñ€Ð¸Ñ‡ÐµÑкие функции. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arctan function. "
+msgstr "ArcTan тригонометричеÑкие функции. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arc tangent function (result is in radians). "
+msgstr "ТригонометричеÑкие функции Ð°Ñ€ÐºÑ‚Ð°Ð½Ð³ÐµÐ½Ñ (результат в радианах). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values. "
+msgstr "Средние значениÑ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value specified by the index. The values may be ranges of cells. "
+msgstr "Возвращает значение указанного индекÑа. Ð—Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ быть диапазонов Ñчеек. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of columns in the range. "
+msgstr "Возвращает количеÑтво Ñтолбцов в диапазоне. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric cosine function (value is in radians). "
+msgstr "ТригонометричеÑкого коÑÐ¸Ð½ÑƒÑ (Значение задаетÑÑ Ð² радианах). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error. "
+msgstr "ПодÑчитывает количеÑтво чиÑловых значений, а не пуÑтыми, текÑÑ‚ или ошибки. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values. "
+msgstr "ПодÑчитывает количеÑтво непуÑÑ‚Ñ‹Ñ… значений. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of blank values. (Note: '' is not blank.) "
+msgstr "ПодÑчитывает количеÑтво пуÑÑ‚Ñ‹Ñ… значений. (Примечание:''не пуÑтой.) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of number of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). "
+msgstr "ПодÑчитывает количеÑтво чиÑло клеток в пределах, которые отвечают Ñтим критериÑм. Критерии могут быть Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ( 'X', 15, 1 3) или теÑта (> 25). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the appropriate date value given numbers for year, month, and day. For example: DATE(2006,2,1) for February 1, 2006. Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "Возврат ÑоответÑтвующего Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð°Ñ‚Ñ‹, указанной на год чиÑло, меÑÑц и день. Ðапример: ДÐТР(2006,2,1) на 1 Ñ„ÐµÐ²Ñ€Ð°Ð»Ñ 2006 года. Примечание: Ð’ Ñтой программе, Ñто 1 день 31 Ð´ÐµÐºÐ°Ð±Ñ€Ñ 1899 и 1900 год не ÑвлÑетÑÑ Ð²Ð¸ÑокоÑным. Ðекоторые программы, иÑпользование 1 ÑÐ½Ð²Ð°Ñ€Ñ 1900 года как день, 1 и лечению 1900 как виÑокоÑный год. Ð’ обоих ÑлучаÑÑ…, хотÑ, даты или поÑле 1 марта 1900, те же Ñамые. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values in the specified field in records that meet the criteria. "
+msgstr "Средние Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð² указанном поле в запиÑи, которые удовлетворÑÑŽÑ‚ критериÑм. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of month for a date value. "
+msgstr "Возвращает день меÑÑца Ð´Ð»Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð°Ñ‚Ñ‹. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error, in the specified field in records that meet the criteria. "
+msgstr "ПодÑчитывает количеÑтво чиÑловых значений, а не пуÑтыми, текÑÑ‚ или ошибка в указанном поле в запиÑи, которые удовлетворÑÑŽÑ‚ критериÑм. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values in the specified field in records that meet the criteria. "
+msgstr "ПодÑчитывает количеÑтво непуÑÑ‚Ñ‹Ñ… значений в указанном поле в запиÑи, которые удовлетворÑÑŽÑ‚ критериÑм. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at the given period of time (the default factor is 2 for double-declining balance). "
+msgstr "Возвращает Ñумму амортизации в конкретный период времени (по умолчанию коÑффициент 2 Ð´Ð»Ñ Ð´Ð²Ð¾Ð¹Ð½Ð¾Ð³Ð¾ ÑƒÐ¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ Ð¾Ñтатка). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in radians into degrees. "
+msgstr "Преобразует значение в радианы в градуÑÑ‹. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value of the specified field in the single record that meets the criteria. "
+msgstr "Возвращает значение указанного Ð¿Ð¾Ð»Ñ Ð² одной запиÑи, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¾Ñ‚Ð²ÐµÑ‡Ð°ÐµÑ‚ уÑтановленным критериÑм. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Возвращает макÑимальное чиÑловых значений в указанном поле в запиÑи, которые удовлетворÑÑŽÑ‚ критериÑм. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values in the specified field in records that meet the criteria. "
+msgstr "Возвращает результат ÑƒÐ¼Ð½Ð¾Ð¶ÐµÐ½Ð¸Ñ Ñ‡Ð¸Ñловых значений в указанном поле в запиÑи, которые удовлетворÑÑŽÑ‚ критериÑм. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Возвращает Ñтандартное отклонение выборки чиÑловых значений в указанном поле в запиÑи, которые удовлетворÑÑŽÑ‚ критериÑм. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Возвращает Ñтандартное отклонение чиÑловых значений в указанном поле в запиÑи, которые удовлетворÑÑŽÑ‚ критериÑм. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Возвращает Ñумму чиÑловых значений в указанном поле в запиÑи, которые удовлетворÑÑŽÑ‚ критериÑм. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Возвращает выборочную диÑперÑию чиÑловых значений в указанном поле в запиÑи, которые удовлетворÑÑŽÑ‚ критериÑм. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "Возвращает разницу в чиÑловых значений в указанном поле в запиÑи, которые удовлетворÑÑŽÑ‚ критериÑм. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest even integer. "
+msgstr "Раунды значение в величине даже ближайшего целого чиÑла. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the values are exactly the same, including case, type, etc. "
+msgstr "Возвращает ИСТИÐÐ, еÑли Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñовпадают, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ñлучай, типу и Ñ‚.д. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns e raised to the value power. "
+msgstr "Возвращает E поднÑÑ‚ на ÑнергетичеÑкой ценноÑтью. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns factorial of the value. "
+msgstr "Возвращает факториал значениÑ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value false. "
+msgstr "Возвращает логичеÑкое значение ложь. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the starting position within string2 of the first occurrence of string1 at or after start. If start is omitted, 1 is assumed. "
+msgstr "Возврат в иÑходное положение в течение string2 от первого поÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð² string1 или поÑле Ñтарта. ЕÑли опущена начать, предполагаетÑÑ, 1. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the future value of repeated payments of money invested at the given rate for the specified number of periods, with optional present value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Возвращает будущую ÑтоимоÑÑ‚ÑŒ повторной выплаты ÑредÑтв, вложенных в данный курÑу на указанное количеÑтво периодов, по желанию Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ¹ ÑтоимоÑтью (по умолчанию 0) и тип платежа (по умолчанию = 0 в конце периода, 1 = начало периода). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the row offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. "
+msgstr "Ищите ÑоответÑтвующее значение Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð² диапазоне и вернуть ÑоответÑтвующее значение в Ñчейке указано в Ñтроке Ñмещение. ЕÑли rangelookup равно 1 (по умолчанию), а не 0, еÑли в течение матча чиÑловые Ñкобки (Match <= значение), а не точное ÑоответÑтвие. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the hour portion of a time or date/time value. "
+msgstr "Возвращает чаÑÑ‹ чаÑти времени или даты / времени. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Results in true-value if logical-expression is TRUE or non-zero, otherwise results in false-value. "
+msgstr "Результаты в иÑтинной ÑтоимоÑти, еÑли логичеÑкие Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¸Ð¼ÐµÐµÑ‚ значение ИСТИÐРили не равно нулю, в противном Ñлучае приводит к ложным ÑтоимоÑти. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns a cell or range reference for the specified row and column in the range. If range is 1-dimensional, then only one of rownum or colnum are needed. If range is 2-dimensional and rownum or colnum are zero, a reference to the range of just the specified column or row is returned. You can use the returned reference value in a range, e.g., sum(A1:INDEX(A2:A10,4)). "
+msgstr "Возвращает Ñчейку или диапазон Ð²ÐµÐ´ÐµÐ½Ð¸Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ñ‹Ñ… Ñтрок и Ñтолбцов в диапазоне. ЕÑли диапазон 1-мерных, то только одна из ROWNUM или colnum нужны. ЕÑли диапазон 2-мерных и ROWNUM colnum или равны нулю, то ÑÑылка на диапазон вÑего указанного Ñтолбца или Ñтроки возвращаетÑÑ. Ð’Ñ‹ можете иÑпользовать возвращенный заданного Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð² диапазоне, например, SUM (A1: ИÐДЕКС (A2: A10, 4)). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value rounded down to the nearest integer (towards -infinity). "
+msgstr "Возвращает значение округлены до ближайшего целого чиÑла (в направлении до беÑконечноÑти). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the interest rate at which the cash flows in the range have a net present value of zero. Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "RВозвращает Ð¿Ñ€Ð¾Ñ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ñтавка, по которой денежные потоки в диапазоне еÑÑ‚ÑŒ чиÑÑ‚Ð°Ñ Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ð°Ñ ÑтоимоÑÑ‚ÑŒ нулÑ. ИÑпользование итеративного процеÑÑа, который вернет # NUM! ошибки, еÑли она не ÑходитÑÑ. Там может быть более чем одно из возможных решений. ОбеÑпечение дополнительное значение думаю, может помочь в некоторых ÑитуациÑÑ…, когда не ÑходÑÑ‚ÑÑ Ð¸Ð»Ð¸ Ñчитает неумеÑтным решение (по умолчанию, полагаю, 10%). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is a reference to a blank cell. "
+msgstr "Возвращает ИСТИÐÐ, еÑли значение ÑвлÑетÑÑ ÑÑылкой на пуÑтую Ñчейку. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error but not NA. "
+msgstr "Возвращает иÑтину, еÑли значение имеет тип ошибки, а не ÐС. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error. "
+msgstr "Возвращает иÑтину, еÑли значение типа ошибки. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Logical (true/false). "
+msgstr "Возвращает ИСТИÐÐ, еÑли Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð° ЛогичеÑкий (иÑтина / ложь). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is the error type NA. "
+msgstr "Возвращает ИСТИÐÐ, еÑли значение ÑвлÑетÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ¾Ð¹ тип ÐС. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is not of type Text. "
+msgstr "Возвращает ИСТИÐÐ, еÑли значение не тип текÑта. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Number (including logical values). "
+msgstr "Возвращает иÑтину, еÑли значение имеет тип номера (Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкие значениÑ). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Text. "
+msgstr "Возвращает иÑтину, еÑли значение имеет тип текÑта. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value. If count is omitted, 1 is assumed. "
+msgstr "Возвращает указанное количеÑтво знаков в текÑте значениÑ. ЕÑли опущена кол, предполагаетÑÑ 1. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of characters in the text value. "
+msgstr "Возвращает количеÑтво Ñимволов в текÑте значениÑ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the natural logarithm of the value. "
+msgstr "Возвращает натуральный логарифм от значениÑ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logarithm of the value using the specified base. "
+msgstr "Возвращает логарифм ÑтоимоÑти Ñ Ð¸Ñпользованием указанной базы. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the base 10 logarithm of the value. "
+msgstr "Возвращает 10 логарифм значениÑ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all uppercase characters converted to lowercase. "
+msgstr "Возвращает значение Ñ Ñ‚ÐµÐºÑтом вÑе заглавные Ñимволы преобразуютÑÑ Ð² нижний региÑÑ‚Ñ€. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return position (the first is 1) in that range. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. If rangelookup is -1, act like 1 but the bracket is match>=value. "
+msgstr "Ищите ÑоответÑтвующее значение Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð² диапазоне и вернуть позиции (Ð¿ÐµÑ€Ð²Ð°Ñ 1) в Ñтом диапазоне. ЕÑли rangelookup равно 1 (по умолчанию), а не 0, еÑли в течение матча чиÑловые Ñкобки (Match <= значение), а не точное ÑоответÑтвие. ЕÑли rangelookup -1, дейÑтвовать как 1, но Ñкобки Ñлово > = значение. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values. "
+msgstr "Возвращает макÑимальное чиÑловых значений. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the specified position. "
+msgstr "Возвращает указанное количеÑтво Ñимволов из текÑтового значениÑ, Ð½Ð°Ñ‡Ð¸Ð½Ð°Ñ Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ð¾Ð¹ позиции. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minimum of the numeric values. "
+msgstr "Возвращает минимальное из чиÑловых значений. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minute portion of a time or date/time value. "
+msgstr "Возвращает минуты чаÑти времени или даты / времени. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the remainder of the first value divided by the second. "
+msgstr "Возвращает оÑтаток от первого Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð° второе. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the month part of a date value. "
+msgstr "Возвращает меÑÑц чаÑти даты. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value if it is a numeric value otherwise an error. "
+msgstr "Возвращает значение, еÑли Ñто чиÑловое значение, в противном Ñлучае ошибки. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the #N/A error value which propagates through most operations. "
+msgstr "Возвращает # Ð / Д значение ошибки, раÑпроÑтранÑющийÑÑ Ñ‡ÐµÑ€ÐµÐ· большинÑтво операций. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns FALSE if value is true, and TRUE if it is false. "
+msgstr "Возвращает FALSE, еÑли значение ÑвлÑетÑÑ Ð¸Ñтинным и верным, еÑли оно ÑвлÑетÑÑ Ð»Ð¾Ð¶Ð½Ñ‹Ð¼. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date/time. "
+msgstr "Возвращает текущую дату / времÑ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of periods at which payments invested each period at the given rate with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period) has the given present value. "
+msgstr "Возвращает количеÑтво периодов, при которой платежи инвеÑтировал каждого периода в данной Ñтавки Ñ Ð±ÑƒÐ´ÑƒÑ‰Ð¸Ð¼ факультативным (по умолчанию 0) и тип платежа (по умолчанию = 0 в конце периода, 1 = начало периода) имеет при нынешней ÑтоимоÑти. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the net present value of cash flows (which may be individual values and/or ranges) at the given rate. The flows are positive if income, negative if paid out, and are assumed at the end of each period. "
+msgstr "Возвращает чиÑтую текущую ÑтоимоÑÑ‚ÑŒ денежных потоков (которые могут быть индивидуальными ценноÑÑ‚Ñми и / или диапазонов) при заданной ÑкороÑти. Потоки ÑвлÑÑŽÑ‚ÑÑ Ð¿Ð¾Ð»Ð¾Ð¶Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ð¼Ð¸, еÑли доход, еÑли негативные выплачены, и, как предполагаетÑÑ Ð² конце каждого периода. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest odd integer. "
+msgstr "Раунды значение в величину до ближайшего нечетного целого. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if any argument is true "
+msgstr "Правда, еÑли один из аргументов ÑвлÑетÑÑ Ð¸Ñтинным "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "The value 3.1415926... "
+msgstr "Значение 3.1415926 ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of each payment that must be invested at the given rate for the specified number of periods to have the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Возврат Ñуммы вÑех платежей, которые должны быть инвеÑтированы в данной Ñтавки за определенное количеÑтво периодов Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ñ‹Ð¼ наÑтоÑщей ÑтоимоÑти, Ñ Ð¾Ð¿Ñ†Ð¸Ð¾Ð½Ð°Ð»ÑŒÐ½Ñ‹Ð¼ будущем (по умолчанию 0) и тип платежа (по умолчанию = 0 в конце периода, 1 = начало периода). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the first value raised to the second value power. "
+msgstr "Возвращает первое значение повышена до второй Ñтепени ценноÑти. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values. "
+msgstr "Возвращает результат ÑƒÐ¼Ð½Ð¾Ð¶ÐµÐ½Ð¸Ñ Ñ‡Ð¸Ñловых значений. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with the first letter of each word converted to uppercase and the others to lowercase. "
+msgstr "Возвращает текÑтовое значение Ñ Ð¿ÐµÑ€Ð²Ð¾Ð¹ буквы каждого Ñлова преобразуютÑÑ Ð² верхний региÑÑ‚Ñ€, а оÑтальные в нижний региÑÑ‚Ñ€. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the present value of the given number of payments each invested at the given rate, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "Возвращает текущую ÑтоимоÑÑ‚ÑŒ данного количеÑтва платежей Каждый из них вложил в данном Ñлучае, Ñ Ð¾Ð¿Ñ†Ð¸Ð¾Ð½Ð°Ð»ÑŒÐ½Ñ‹Ð¼ будущем (по умолчанию 0) и тип платежа (по умолчанию = 0 в конце периода, 1 = начало периода). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in degrees into radians. "
+msgstr "Преобразование Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð² градуÑах в радианах. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the rate at which the given number of payments each invested at the given rate has the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "Возврат Ñтавки, при которой данное количеÑтво платежей Каждый из них вложил в данный ÐºÑƒÑ€Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ð¾Ð¹ текущей ÑтоимоÑти, по желанию Ñ Ð±ÑƒÐ´ÑƒÑ‰Ð¸Ð¼ (по умолчанию 0) и тип платежа (по умолчанию = 0 в конце периода, 1 = начало периода). ИÑпользование итеративного процеÑÑа, который вернет # NUM! ошибки, еÑли она не ÑходитÑÑ. Там может быть более чем одно из возможных решений. ОбеÑпечение дополнительное значение думаю, может помочь в некоторых ÑитуациÑÑ…, когда не ÑходÑÑ‚ÑÑ Ð¸Ð»Ð¸ Ñчитает неумеÑтным решение (по умолчанию, полагаю, 10%). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the specified number of characters starting from the specified position replaced by text2. "
+msgstr "Возвращает text1 Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð½Ñ‹Ð¼ количеÑтвом Ñимволов, Ð½Ð°Ñ‡Ð¸Ð½Ð°Ñ Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ð¾Ð¹ позиции заменен text2. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text repeated the specified number of times. "
+msgstr "Возвращает текÑÑ‚ повторÑетÑÑ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ð¾Ðµ чиÑло раз. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the end. If count is omitted, 1 is assumed. "
+msgstr "Возвращает указанное количеÑтво Ñимволов из текÑтового значениÑ, Ð½Ð°Ñ‡Ð¸Ð½Ð°Ñ Ñ ÐºÐ¾Ð½Ñ†Ð°. ЕÑли опущена кол, предполагаетÑÑ 1. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value to the specified number of decimal places. If precision is negative, then round to powers of 10. The default precision is 0 (round to integer). "
+msgstr "Раунды значение до указанного количеÑтва деÑÑтичных разрÑдов. ЕÑли точноÑÑ‚ÑŒ ÑвлÑетÑÑ Ð½ÐµÐ³Ð°Ñ‚Ð¸Ð²Ð½Ñ‹Ð¼, то круглый Ñтепени 10. ТочноÑÑ‚ÑŒ по умолчанию равна 0 (круглый в целое). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of rows in the range. "
+msgstr "Возвращает количеÑтво Ñтрок в диапазоне. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the second portion of a time or date/time value (truncated to an integer). "
+msgstr "Возвращает Ð’Ñ‚Ð¾Ñ€Ð°Ñ Ñ‡Ð°ÑÑ‚ÑŒ времени или даты / времени (обрезаютÑÑ Ð´Ð¾ целого чиÑла). "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric sine function (value is in radians) "
+msgstr "ТригонометричеÑкие функции ÑÐ¸Ð½ÑƒÑ (Значение задаетÑÑ Ð² радианах) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at each period of time using the straight-line method. "
+msgstr "Возвращает Ñумму амортизации в каждый период времени Ñ Ð¸Ñпользованием линейного метода. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Square root of the value "
+msgstr "Квадратный корень из Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values. "
+msgstr "Возвращает Ñтандартное отклонение выборки чиÑловых значений. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values. "
+msgstr "Возвращает Ñтандартное отклонение чиÑловых значений. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the all occurrences of oldtext replaced by newtext. If occurrence is present, then only that occurrence is replaced. "
+msgstr "Возвращает text1 Ñо вÑех вхождений oldtext заменены newtext. При возникновении приÑутÑтвует, то только то, что заменили возникновениÑ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Adds the numeric values. The values to the sum function may be ranges in the form similar to A1:B5. "
+msgstr "ДобавлÑет чиÑловых значений. Ð—Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð² Ñумме Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚ быть диапазонов в виде аналогичного Ð1: Ð’5. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sums the numeric values of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). If range2 is present, then range1 is tested and the corresponding range2 value is summed. "
+msgstr "Сумма чиÑловых значений Ñчеек в диапазоне, которые отвечают Ñтим критериÑм. Критерии могут быть Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ( 'X', 15, 1 3) или теÑта (> 25). ЕÑли Range2 приÑутÑтвует, то Range1 проверена и ÑоответÑтвующие Range2 Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÑуммируютÑÑ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Depreciation by Sum of Year's Digits method. "
+msgstr "Ðмортизации Ñумма цифр методом Года. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value or else a null string. "
+msgstr "Возвращает значение текÑта, либо пуÑÑ‚Ð°Ñ Ñтрока. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric tangent function (value is in radians) "
+msgstr "ТригонометричеÑкие функции каÑательной (Значение задаетÑÑ Ð² радианах) "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the time value given the specified hour, minute, and second. "
+msgstr "Возвращает значение времени Ñ ÑƒÑ‡ÐµÑ‚Ð¾Ð¼ указанного чаÑа, минуты и Ñекунды. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date (an integer). Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "Возвращает текущую дату (чиÑло). Примечание: Ð’ Ñтой программе, Ñто 1 день 31 Ð´ÐµÐºÐ°Ð±Ñ€Ñ 1899 и 1900 год не ÑвлÑетÑÑ Ð²Ð¸ÑокоÑным. Ðекоторые программы, иÑпользование 1 ÑÐ½Ð²Ð°Ñ€Ñ 1900 года как день, 1 и лечению 1900 как виÑокоÑный год. Ð’ обоих ÑлучаÑÑ…, хотÑ, даты или поÑле 1 марта 1900, те же Ñамые. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with leading, trailing, and repeated spaces removed. "
+msgstr "Возвращает значение Ñ Ñ‚ÐµÐºÑтом в начале, и повторил проÑтранÑтва удалено. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value true. "
+msgstr "Возвращает логичеÑкое значение ИСТИÐÐ. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Truncates the value to the specified number of decimal places. If precision is negative, truncate to powers of 10. "
+msgstr "УÑекает значение до указанного количеÑтва деÑÑтичных разрÑдов. ЕÑли точноÑÑ‚ÑŒ ÑвлÑетÑÑ Ð¾Ñ‚Ñ€Ð¸Ñ†Ð°Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ð¼, уÑечение полномочий по 10. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all lowercase characters converted to uppercase. "
+msgstr "Возвращает значение Ñ Ñ‚ÐµÐºÑтом вÑе Ñтрочные Ñимволы преобразуютÑÑ Ð² верхний региÑÑ‚Ñ€. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts the specified text value into a numeric value. Various forms that look like numbers (including digits followed by %, forms that look like dates, etc.) are handled. This may not handle all of the forms accepted by other spreadsheets and may be locale dependent. "
+msgstr "Преобразует заданное значение текÑÑ‚ в чиÑловое значение. Различные формы, которые выглÑдÑÑ‚ как номера (чиÑла цифр, за которыми%, формы, которые выглÑдÑÑ‚ как дата и Ñ‚.д.) обрабатываютÑÑ. Это не может обрабатывать вÑе формы принимаютÑÑ Ð¿Ð¾ другим таблицам и локали могут быть завиÑимыми. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values. "
+msgstr "Возвращает выборочную диÑперÑию чиÑловых значений. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values. "
+msgstr "Возвращает разницу в чиÑловых значениÑÑ…. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the column offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match>=value) instead of exact match. "
+msgstr "Ищите ÑоответÑтвующее значение Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð² диапазоне и вернуть ÑоответÑтвующее значение в Ñчейке указано в Ñтолбце ÑмещениÑ. ЕÑли rangelookup равно 1 (по умолчанию), а не 0, еÑли в течение матча чиÑловые Ñкобки (матч> = значение), а не точное ÑоответÑтвие. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of week specified by the date value. If type is 1 (the default), Sunday is day and Saturday is day 7. If type is 2, Monday is day 1 and Sunday is day 7. If type is 3, Monday is day 0 and Sunday is day 6. "
+msgstr "Возвращает день недели по указанной даты. ЕÑли тип 1 (по умолчанию), воÑкреÑенье и в Ñубботу день Ñто 7-й день. ЕÑли тип 2, понедельник День 1 и воÑкреÑеньÑм день 7. ЕÑли тип 3, понедельник День 0 и воÑкреÑеньÑм день 6. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the year part of a date value. "
+msgstr "Возвращает год чаÑти даты. "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value"
+msgstr "Значение"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value1, value2, ..."
+msgstr "значение1, значение2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "valueX, valueY"
+msgstr "valueX, valueY"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "index, value1, value2, ..."
+msgstr "индекÑ, значение1, значение2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range"
+msgstr "линиÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, criteria"
+msgstr "диапазон, критерии"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "year, month, day"
+msgstr "год, меÑÑц, день"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "databaserange, fieldname, criteriarange"
+msgstr "databaserange, FieldName, criteriarange"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period [, factor]"
+msgstr "ÑтоимоÑÑ‚ÑŒ, утиль, Ñрок Ñлужбы, Ñрок [фактор]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "string1, string2 [, start]"
+msgstr "string1, string2 [, начало]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [pv, [paytype]]"
+msgstr "КурÑ, N, оплата, [PV, [PayType]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, row, [rangelookup]"
+msgstr "значениÑ, диапазон, Ñтрока [rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "logical-expression, true-value, false-value"
+msgstr "логичеÑкие выражениÑ, иÑтинные значениÑ, ложные значениÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, rownum, colnum"
+msgstr "диапазона, ROWNUM, colnum"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, [guess]"
+msgstr "Диапазон, [думаю]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, count"
+msgstr "ТекÑÑ‚, кол-во"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, base"
+msgstr "Значение, на базе"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, [rangelookup]"
+msgstr "значениÑ, диапазон, [rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, start, length"
+msgstr "текÑÑ‚, начало, длина"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, payment, pv, [fv, [paytype]]"
+msgstr "Оцените, оплата, PV, [Ф.В., [PayType]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, value1, value2, ..."
+msgstr "Ñтавка, значение1, значение2, ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, pv, [fv, [paytype]]"
+msgstr "Оцените, N, PV, [Ф.В., [PayType]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [fv, [paytype]]"
+msgstr "Оцените, N, оплата, [Ф.В., [PayType]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "n, payment, pv, [fv, [paytype, [guess]]]"
+msgstr "N, оплата, PV, [Ф.В., [PayType, [думаю]]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, start, length, text2"
+msgstr "текÑÑ‚1, начало, длина, text2"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, [precision]"
+msgstr "Значение, [Precision]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime"
+msgstr "ÑтоимоÑÑ‚ÑŒ, утиль, жизнь"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period"
+msgstr "ÑтоимоÑÑ‚ÑŒ, утиль, Ñрок Ñлужбы, Ñрок"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, oldtext, newtext [, occurrence]"
+msgstr "текÑÑ‚1, oldtext, newtext [, возникновение]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range1, criteria [, range2]"
+msgstr "Range1, критерии [, Range2]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "hour, minute, second"
+msgstr "чаÑÑ‹, минуты, Ñекунды"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, col, [rangelookup]"
+msgstr "значениÑ, диапазон, Col, [rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date, [type]"
+msgstr "Дата, [тип]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date"
+msgstr "Ñвидание"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["all", "stat", "lookup", "datetime", "financial", "test", "math", Text]
+#msgstr [ "вÑе", "Ñтать", "поиÑк", "DateTime", "финанÑовый", "ИÑпытание", "математика", текÑÑ‚]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "All"
+msgstr "Ð’Ñе"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Statistics"
+msgstr "СтатиÑтика"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Lookup"
+msgstr "ПоиÑк"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Date & Time"
+msgstr "Дата & времÑ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Financial"
+msgstr "ФинанÑовые"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Test"
+msgstr "Проверка"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Math"
+msgstr "Math"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cells to Graph"
+msgstr "Клеток к графике"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Graph"
+msgstr "Задать клеток график"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph Type"
+msgstr "Тип диаграммы"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "filter:alpha(opacity=90);opacity:.9;"
+msgstr "Фильтр: Alpha (Opacity = 90); непрозрачноÑти: .9;"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain"
+msgstr "Равнина"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph"
+msgstr "Графика"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Pie Chart"
+msgstr "ÐšÑ€ÑƒÐ³Ð¾Ð²Ð°Ñ Ð´Ð¸Ð°Ð³Ñ€Ð°Ð¼Ð¼Ð°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Help"
+msgstr "Помощь"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal Bar"
+msgstr "Горизонтальные Бар"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical Bar"
+msgstr "Ð’ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ð‘Ð°Ñ€"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Line Chart"
+msgstr "Линейный график"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plot Points"
+msgstr "УчаÑток Очки"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown range name"
+msgstr "ÐеизвеÑтное Ð¸Ð¼Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hide Help"
+msgstr "Hide Help"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Max "
+msgstr "ÐœÐ°ÐºÑ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Min "
+msgstr "Мин "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " OK "
+msgstr " OK "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Cancel]"
+msgstr "[Отмена]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "TRUE"
+msgstr "TRUE"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "FALSE"
+msgstr "ЛОЖЬ"
+
diff --git a/po/zh_CN.po b/po/zh_CN.po
new file mode 100644
index 0000000..3f6a4dc
--- /dev/null
+++ b/po/zh_CN.po
@@ -0,0 +1,1464 @@
+# Copyright (C) 2010 THE PACKAGE"S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# olpc user <olpc@localhost.localdomain>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: SocialCalcActivity.activity\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-01-07 14:46+0000\n"
+"PO-Revision-Date: 2010-01-09 21:53+0530\n"
+"Last-Translator: Diksha<dksh.khatri@gmail.com>\n"
+"Language-Team: Hindi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: activity/activity.info:2
+msgid "SocialCalcActivity"
+msgstr "SocialCalcActivity"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:10
+#msgid "t"
+#msgstr "å¨"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:13
+msgid "Browser not supported. "
+msgstr "æµè§ˆå™¨ä¸æ”¯æŒã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:14
+msgid "Internal SocialCalc error (probably an internal bug):"
+msgstr "内部SocialCalc错误(å¯èƒ½æ˜¯ä¸€ä¸ªå†…部错误): "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:20
+msgid "Unknown col type item"
+msgstr "未知山å£åž‹é¡¹ç›®"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:21
+msgid "Unknown row type item"
+msgstr "未知行类型的项目"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:22
+msgid "Unknown line type"
+msgstr "未知线型"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:28
+msgid "Unknown cell type item"
+msgstr "未知细胞型项目"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:36
+msgid "Unknown sheet command: "
+msgstr "未知的工作表命令:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:37
+msgid "Unknown set coord command: "
+msgstr "未知设置å标命令:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:38
+msgid "Unknown command: "
+msgstr "未知命令:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:42
+msgid "Circular reference to "
+msgstr "通知æåŠ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:52
+#msgid "padding:2px 2px 1px 2px;vertical-align:top;"
+#msgstr "填充:2px 2px 1px 2px;垂直对é½ï¼šé¡¶éƒ¨;"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:53
+msgid "normal normal"
+msgstr "正常正常"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:54
+msgid "small"
+msgstr "å°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:55
+msgid "Verdana,Arial,Helvetica,sans-serif"
+msgstr "宋体,Verdana,Arial字体,海尔维希,无衬线"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:92
+msgid "Render Context must have a sheet object"
+msgstr"渲染上下文必须有一个表对象"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Executing..."
+msgstr "执行..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Displaying..."
+msgstr "显示..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Ordering..."
+msgstr "订购..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating..."
+msgstr "计算..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculating... Loading Sheet..."
+msgstr "计算...载入中æ¿..."
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "doing server function "
+msgstr "åšæœåŠ¡å™¨åŠŸèƒ½"
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " in cell "
+msgstr "细胞"
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Calculation start..."
+msgstr "计算开始..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SUM"
+msgstr "森"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Multi-line text: Click icon on right to edit]"
+msgstr "[多行文本:点击图标编辑æƒ]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function "
+msgstr "未知的函数"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane vertically"
+msgstr "拖动é”定窗格垂直"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Drag to lock pane horizontally"
+msgstr "拖动é”定窗格水平"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Center"
+msgstr "居中对é½"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Left"
+msgstr "左对é½"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Align Right"
+msgstr "å³å¯¹é½"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Alignment"
+msgstr "对é½"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit"
+msgstr "审计"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Audit Trail This Session"
+msgstr "审计跟踪此会è¯"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto"
+msgstr "自动"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto Sum"
+msgstr "自动求和"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Auto w/ commas"
+msgstr "自动瓦特/逗å·"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Automatic"
+msgstr "自动"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Background"
+msgstr "背景"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold"
+msgstr "大胆"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold &amp; Italics"
+msgstr "大胆和斜体"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bold Italic"
+msgstr "粗斜体"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders"
+msgstr "边框"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders Off"
+msgstr "边界关闭"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Borders On"
+msgstr "接壤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom"
+msgstr "底"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Bottom Border"
+msgstr "下边框"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CELL SETTINGS"
+msgstr "细胞设置"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "CSV format"
+msgstr "CSVæ ¼å¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cancel"
+msgstr"å–消"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Category"
+msgstr "类别"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Center"
+msgstr "中心"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear"
+msgstr "清除"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clear SocialCalc Clipboard"
+msgstr "清除SocialCalc剪贴æ¿"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Clipboard"
+msgstr "剪贴æ¿"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Color"
+msgstr "颜色"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Column"
+msgstr "列"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Comment"
+msgstr "æ„è§"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Copy"
+msgstr "å¤åˆ¶"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Custom"
+msgstr "自定义"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cut"
+msgstr "剪切"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default"
+msgstr "默认"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Alignment"
+msgstr "默认对é½"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Column Width"
+msgstr "默认列宽"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Font"
+msgstr "默认字体"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Format"
+msgstr "默认格å¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Default Padding"
+msgstr "默认填充"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete"
+msgstr "删除"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Column"
+msgstr "删除列"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Delete Row"
+msgstr "删除行"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Description"
+msgstr "说明"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Display Clipboard in"
+msgstr "显示剪贴æ¿ä¸­"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Down"
+msgstr "打倒"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Edit"
+msgstr "编辑"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Existing Names"
+msgstr "现有å称"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Family"
+msgstr "家庭"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Down"
+msgstr "å‘下填充"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Fill Right"
+msgstr "填满æƒ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Font"
+msgstr "字体"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Format"
+msgstr "æ ¼å¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula"
+msgstr "方程å¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Function List"
+msgstr "功能表"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Functions"
+msgstr "函数"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Grid"
+msgstr "网格"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hidden"
+msgstr "éšè—"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal"
+msgstr "横å‘"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Column"
+msgstr "æ’入列"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Insert Row"
+msgstr "æ’入行"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Italic"
+msgstr "倾斜"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Last Sort"
+msgstr "最åŽæŽ’åº"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left"
+msgstr "å·¦"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Left Border"
+msgstr "左边框"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "List"
+msgstr "åå•"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Load SocialCalc Clipboard With This"
+msgstr "è´Ÿè½½SocialCalc剪贴æ¿æœ‰äº†è¿™ä¸ª"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Major Sort"
+msgstr "主è¦æŽ’åºl"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Manual"
+msgstr "手册"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Merge Cells"
+msgstr "åˆå¹¶å•å…ƒæ ¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Middle"
+msgstr "中间"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Minor Sort"
+msgstr "å°æŽ’åº"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Insert"
+msgstr "移动æ’å…¥"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Move Paste"
+msgstr "移动粘贴"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Multi-line Input Box"
+msgstr "多行输入框"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Name"
+msgstr "姓å"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Names"
+msgstr "å称"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "No padding"
+msgstr "æ— å¡«å……"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Normal"
+msgstr "正常"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number"
+msgstr "å·ç "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Number Horizontal"
+msgstr "å·ç æ°´å¹³"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "OK"
+msgstr "确定"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Padding"
+msgstr "å¡«å……"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Page Name"
+msgstr "网页å称"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste"
+msgstr "粘贴"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Paste Formats"
+msgstr "粘贴格å¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain Text"
+msgstr "纯文本"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalc"
+msgstr "Recalc"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Recalculation"
+msgstr "é‡æ–°è®¡ç®—"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " Redo"
+msgstr "é‡åš"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right"
+msgstr "å³"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Right Border"
+msgstr "å³è¾¹ç•Œ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SHEET SETTINGS"
+msgstr "表设置"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save"
+msgstr "ä¿å­˜"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Save to"
+msgstr "ä¿å­˜åˆ°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cell Contents"
+msgstr "设置å•å…ƒæ ¼å†…容"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Sort"
+msgstr "设置å•å…ƒæ ¼æŽ’åº"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Value To"
+msgstr "设置其值为"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set to Link format"
+msgstr "设置为链接的格å¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set/Clear Move From"
+msgstr "设置/清除摆脱"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Cell Settings"
+msgstr "显示电池设置"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show Sheet Settings"
+msgstr "显示表设置"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Show in new browser window"
+msgstr "显示在新的æµè§ˆå™¨çª—å£"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Size"
+msgstr "大å°"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SocialCalc-save format"
+msgstr "SocialCalc,ä¿å­˜æ ¼å¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort"
+msgstr "排åº"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sort Cells"
+msgstr "排åºç»†èƒž"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Swap Colors"
+msgstr "交æ¢è‰²å½©"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Tab-delimited format"
+msgstr "制表符分隔格å¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text"
+msgstr "文本"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Text Horizontal"
+msgstr "文本水平"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "This is a<br>sample"
+msgstr "这是一个<br>样本"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top"
+msgstr "顶"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Top Border"
+msgstr "边框"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "UNDONE STEPS"
+msgstr "撤消步骤"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "URL"
+msgstr "网å€"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Undo"
+msgstr "撤消"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unmerge Cells"
+msgstr "å–消åˆå¹¶å•å…ƒæ ¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Up"
+msgstr "å‘上"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Value"
+msgstr "值"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical"
+msgstr "åž‚ç›´"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Workspace"
+msgstr "工作区"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[New]"
+msgstr "[æ–°]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[None]"
+msgstr "[æ— ]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[select range]"
+msgstr "[选择范围]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
+#msgstr ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
+#msgstr ["太阳","一","二","三","四","五","六"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["January", "February", "March", "April", "May", "June", "July", "August", "September","October", "November", "December"]
+#msgstr ["一月","二月","三月","04","五月","六月","七月","八月","ä¹æœˆ","å月","11","12"]
+
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+#msgstr ["1","二月","三月","四月","五月","六月","七月","八月","ä¹æœˆ","å月","11","12"]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "AM"
+#msgstr "上åˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "A"
+#msgstr "å­—æ¯a"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "PM"
+#msgstr "下åˆ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid "P"
+#msgstr "P"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed number exponent"
+msgstr "ä¸æ­£ç¡®å½¢æˆæ•°å­—的指数"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unexpected character in formula"
+msgstr "æ„外的字符公å¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed string"
+msgstr "ä¸æ­£ç¡®ç»„æˆçš„字符串"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Improperly formed special value"
+msgstr "ä¸å½“å½¢æˆäº†ç‰¹æ®Šçš„价值"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula (two operators inappropriately in a row)"
+msgstr "错误(两个ç»è¥è€…ä¸é€‚当地连续)在公å¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing open parenthesis in list with comma(s)."
+msgstr "缺少括å·ä¸Žé€—å·ï¼ˆæ‹§ï¼‰ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Closing parenthesis without open parenthesis. "
+msgstr "没有开放的括å·å³æ‹¬å·ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing close parenthesis."
+msgstr "缺少å³æ‹¬å·ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Missing operand."
+msgstr "缺少æ“作数。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula."
+msgstr "错误的公å¼ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error value in formula"
+msgstr "错误值公å¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Error in formula resulting in bad value"
+msgstr "错误的价值,造æˆä¸è‰¯å…¬å¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in range value:"
+msgstr "在范围值公å¼çš„结果:"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Formula results in an bad numeric value"
+msgstr "一级方程å¼åœ¨ä¸€ä¸ªç³Ÿç³•çš„结果数值"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Numeric overflow"
+msgstr "数值溢出"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet unavailable:"
+msgstr "表ä¸å¯ç”¨ï¼š"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cell reference missing when expected."
+msgstr "å•å…ƒæ ¼å¼•ç”¨å¤±è¸ªçš„预期。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sheet name missing when expected."
+msgstr "工作表å失踪的预期。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Circular name reference to name"
+msgstr "通知å称中æåŠçš„åå­—"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown name"
+msgstr "未知的å称"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Incorrect arguments to function"
+msgstr "ä¸æ­£ç¡®çš„å‚数函数"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown function"
+msgstr "未知的函数"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LN argument must be greater than 0"
+msgstr "è¡Œå‚数必须大于0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG10 argument must be greater than 0"
+msgstr "LOG10å‚数必须大于0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG second argument must be numeric greater than 0"
+msgstr "日志的第二个å‚数必须是数字大于0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "LOG first argument must be greater than 0"
+msgstr "日志第一个å‚数必须大于0"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "ROUND second argument must be numeric"
+msgstr "圆的第二个å‚数必须是数字"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "DDB life must be greater than 1"
+msgstr "è”苯åŒé…¯ç”Ÿæ´»å¿…须大于1"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "SLN life must be greater than 1"
+msgstr "å‰å“¨æ·‹å·´ç»“的生活必须大于1"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Absolute value function. "
+msgstr "ç»å¯¹çš„价值功能。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arccosine function. "
+msgstr "三角å余弦函数。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if all arguments are true. "
+msgstr "真正的,如果所有å‚数都是真的。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arcsine function. "
+msgstr "三角å正弦函数。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arctan function. "
+msgstr "三角arctan功能。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric arc tangent function (result is in radians). "
+msgstr "三角弧正切函数(结果为弧度)。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values. "
+msgstr "å¹³å‡æ•°çš„值。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value specified by the index. The values may be ranges of cells. "
+msgstr "返回索引所指定的值。值å¯ä»¥æ˜¯å•å…ƒæ ¼åŒºåŸŸã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of columns in the range. "
+msgstr "返回该区域中的列数。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric cosine function (value is in radians). "
+msgstr "三角余弦函数(值在弧度)。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error. "
+msgstr "伯爵的数值数,ä¸ä¸ºç©ºï¼Œæ–‡æœ¬æˆ–错误。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values. "
+msgstr "伯爵的一些éžç©ºå€¼ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of blank values. (Note: '' is not blank.) "
+msgstr "伯爵的空白值的个数。(注:''ä¸æ˜¯ç©ºç™½ã€‚)"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of number of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). "
+msgstr "计数范围中的细胞数目符åˆæ ‡å‡†ã€‚准则å¯èƒ½æ˜¯ä¸€ä¸ªå€¼ï¼ˆ'×',15,1 +3)或测试(25)。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the appropriate date value given numbers for year, month, and day. For example: DATE(2006,2,1) for February 1, 2006. Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "返回值给予适当的日期为今年数字,月,日。例如:对于2006å¹´2月1日日期(2006,2,1)。注:在这个程åºä¸­ï¼Œç¬¬1天是1899å¹´12月31日和1900年是ä¸æ˜¯é—°å¹´ã€‚æŸäº›ç¨‹åºä½¿ç”¨00å¹´1月1å·ï¼Œä½œä¸ºç¬¬1天,并以此作为闰年1900年。在这两ç§æƒ…况,ä¸è¿‡ï¼Œæ—¥æˆ–之åŽ00å¹´3月1日的日期,是相åŒçš„。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Averages the values in the specified field in records that meet the criteria. "
+msgstr "å¹³å‡æ•°çš„记录在指定的字段值符åˆæ ‡å‡†ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of month for a date value. "
+msgstr "返回的日期值的一个月里的日å­ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of numeric values, not blank, text, or error, in the specified field in records that meet the criteria. "
+msgstr "伯爵的数值数,ä¸ä¸ºç©ºï¼Œæ–‡æœ¬ï¼Œæˆ–在指定的字段错误的记录,符åˆæ ‡å‡†ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Counts the number of non-blank values in the specified field in records that meet the criteria. "
+msgstr "伯爵的éžæŒ‡å®šé¢†åŸŸçš„空白值的记录符åˆæ¡ä»¶ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at the given period of time (the default factor is 2 for double-declining balance). "
+msgstr "返回在特定时期的折旧é¢ï¼ˆé»˜è®¤å› ç´ æ˜¯2åŒå€ä½™é¢é€’å‡ï¼‰ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in radians into degrees. "
+msgstr "在转æ¢ä¸ºåº¦å¼§åº¦çš„价值。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value of the specified field in the single record that meets the criteria. "
+msgstr "返回å•ä¸ªè®°å½•ä¸­ç¬¦åˆæ¡ä»¶çš„指定字段的值。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "返回在指定字段的数值最高记录符åˆæ¡ä»¶ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values in the specified field in records that meet the criteria. "
+msgstr "返回乘以记录指定字段的数值符åˆæ¡ä»¶çš„结果。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "返回样本标准差在指定字段中记录的数值符åˆæ ‡å‡†ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values in the specified field in records that meet the criteria. "
+msgstr "返回在指定字段的记录数值的标准差符åˆæ ‡å‡†ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sum of the numeric values in the specified field in records that meet the criteria. "
+msgstr "返回在指定字段中记录的数值总和符åˆæ ‡å‡†ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "返回在指定字段中记录的数值样本方差符åˆæ ‡å‡†ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values in the specified field in records that meet the criteria. "
+msgstr "返回在指定字段中记录的数值差异符åˆæ ‡å‡†ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest even integer. "
+msgstr "回åˆçš„幅度为最接近的价值了å¶æ•°ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the values are exactly the same, including case, type, etc. "
+msgstr "返回true如果值是完全相åŒçš„,包括案例,类型等"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns e raised to the value power. "
+msgstr "返回的ä½ç½®ä¸Šå‡åˆ°ä»·å€¼çš„力é‡ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns factorial of the value. "
+msgstr "返回值的阶乘。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value false. "
+msgstr "返回逻辑值虚å‡çš„。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the starting position within string2 of the first occurrence of string1 at or after start. If start is omitted, 1 is assumed. "
+msgstr "内返回的字符串第一次出现的字符串开始时或以åŽå¼€å§‹çš„ä½ç½®ã€‚如果开始被çœç•¥ï¼Œè®¤ä¸ºæ˜¯1。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the future value of repeated payments of money invested at the given rate for the specified number of periods, with optional present value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "返回旨在为指定数é‡çš„时期给予投资资金é‡å¤çŽ‡æ”¯ä»˜çš„未æ¥ä»·å€¼ï¼ŒçŽ°å€¼ä¸Žå¯é€‰ï¼ˆé»˜è®¤0)和支付方å¼ï¼ˆé»˜è®¤å€¼0 =期末,1 =期åˆï¼‰ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the row offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. "
+msgstr "中查找的范围内给定值的匹é…值,并返回由å移行指定的å•å…ƒæ ¼å¯¹åº”的值。如果rangelookup为1(默认值),而ä¸æ˜¯0,如果匹é…括å·å†…的数字(符åˆ=值)而ä¸æ˜¯å®Œå…¨åŒ¹é…。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the hour portion of a time or date/time value. "
+msgstr "返回一个å°æ—¶çš„时间或日期部分/时间值。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Results in true-value if logical-expression is TRUE or non-zero, otherwise results in false-value. "
+msgstr "结果的真实价值,如果逻辑表达å¼ä¸ºçœŸæˆ–éžé›¶ï¼Œå¦åˆ™è™šå‡ä»·å€¼çš„结果。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns a cell or range reference for the specified row and column in the range. If range is 1-dimensional, then only one of rownum or colnum are needed. If range is 2-dimensional and rownum or colnum are zero, a reference to the range of just the specified column or row is returned. You can use the returned reference value in a range, e.g., sum(A1:INDEX(A2:A10,4)). "
+msgstr "返回一个å•å…ƒæ ¼æˆ–区域的å‚考指定的行和列的范围内。如果范围是1维,那么åªæœ‰ROWNUM给出或colnum之一是需è¦çš„。如果范围为2ç»´å’ŒROWNUM给出或colnum是零,一æ到结果的真实价值,如果逻辑表达å¼ä¸ºçœŸæˆ–éžé›¶ï¼Œå¦åˆ™è™šå‡ä»·å€¼çš„结果。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value rounded down to the nearest integer (towards -infinity). "
+msgstr "返回值å‘下调整至最接近的整数(对-无穷大)。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the interest rate at which the cash flows in the range have a net present value of zero. Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "返回时的利率范围内的现金æµé‡ä¸ºé›¶çš„净现值。使用一个åå¤çš„过程,将返回#NUMï¼çš„错误,如果ä¸è¡”接。å¯èƒ½æœ‰å¤šä¸ªå¯èƒ½çš„解决方案。æä¾›å¯é€‰ä¼°è®¡å€¼å¯èƒ½æœ‰åŠ©äºŽæŸäº›æƒ…况下,它ä¸è¡”接或å‘现ä¸æ°å½“的解决方案(默认的猜测是10%)。 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is a reference to a blank cell. "
+msgstr "返回true如果值是一个空白å•å…ƒæ ¼å¼•ç”¨ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error but not NA. "
+msgstr "返回true如果该值类型的错误,但没有ä¸é€‚用的。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Error. "
+msgstr "返回true如果该值的类型错误的。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Logical (true/false). "
+msgstr "返回true如果值类型逻辑(真/å‡ï¼‰ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is the error type NA. "
+msgstr "返回true如果值是错误类型ä¸é€‚用。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is not of type Text. "
+msgstr "返回true如果该值ä¸æ˜¯ç±»åž‹çš„文本。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Number (including logical values). "
+msgstr "返回true如果该值类型(包括逻辑值)。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns true if the value is of type Text. "
+msgstr "返回true如果该值类型文本。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value. If count is omitted, 1 is assumed. "
+msgstr "返回的文本值指定的字符数。如果罪å被çœç•¥ï¼Œè®¤ä¸ºæ˜¯1。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of characters in the text value. "
+msgstr "返回的文本值的字符数。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the natural logarithm of the value. "
+msgstr "返回值的自然对数。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logarithm of the value using the specified base. "
+msgstr "返回值的对数使用指定的基础。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the base 10 logarithm of the value. "
+msgstr "返回基地的10值对数。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all uppercase characters converted to lowercase. "
+msgstr "返回与转æ¢ä¸ºå°å†™æ‰€æœ‰å¤§å†™å­—符的文本值。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return position (the first is 1) in that range. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. If rangelookup is -1, act like 1 but the bracket is match>=value. "
+msgstr "中查找的范围内给定值,并返回匹é…值的ä½ç½®ï¼ˆç¬¬ä¸€ä¸ªæ˜¯1)在这个范围内。如果rangelookup为1(默认值),而ä¸æ˜¯0,如果匹é…括å·å†…的数字(符åˆ=值),而ä¸æ˜¯å®Œå…¨åŒ¹é…。如果rangelookup为-1,这样一行为,但括å·åŒ¹é…=值。 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the maximum of the numeric values. "
+msgstr "返回的数值最大。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the specified position. "
+msgstr "从文本返回从指定ä½ç½®å¼€å§‹å€¼æŒ‡å®šçš„字符数。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minimum of the numeric values. "
+msgstr "返回数值的最低é™åº¦ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the minute portion of a time or date/time value. "
+msgstr "返回1分钟的时间或日期部分/时间值。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the remainder of the first value divided by the second. "
+msgstr"返回由第二除以第一个值的其余部分。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the month part of a date value. "
+msgstr "返回日期值一个月。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the value if it is a numeric value otherwise an error. "
+msgstr "返回值如果它是一个数值,å¦åˆ™ä¸€ä¸ªé”™è¯¯ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the #N/A error value which propagates through most operations. "
+msgstr "返回#N / A错误值,大多数的æ“作,通过传播。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns FALSE if value is true, and TRUE if it is false. "
+msgstr "如果返回FALSE值为真,真,如果是å‡çš„。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date/time. "
+msgstr "返回当å‰çš„日期/时间。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of periods at which payments invested each period at the given rate with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period) has the given present value. "
+msgstr "返回时的付款期é™åœ¨ä¸ŽæŠ•èµ„å¯é€‰æœªæ¥å€¼ï¼ˆé»˜è®¤0)和付款方å¼ç»™äºˆæ¯ä¸ªå‘¨æœŸçŽ‡ï¼ˆé»˜è®¤å€¼ä¸º0 =期末,1 =期åˆï¼‰æ•°æœ‰é‰´äºŽç›®å‰çš„价值。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the net present value of cash flows (which may be individual values and/or ranges) at the given rate. The flows are positive if income, negative if paid out, and are assumed at the end of each period. "
+msgstr "返回的净现金æµé‡çš„现值(å¯èƒ½æ˜¯ä¸ªäººä»·å€¼å’Œ/或区域)在给定的速度。的æµåŠ¨æ˜¯æ­£é¢çš„,如果收入,如果支付了负,并且在æ¯ä¸ªæœŸæœ«æ‰¿æ‹…。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value up in magnitude to the nearest odd integer. "
+msgstr "回åˆçš„幅度为最接近的奇数的价值了。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "True if any argument is true "
+msgstr "True,如果任何å‚数是真正的"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "The value 3.1415926... "
+msgstr "价值3.1415926 ..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of each payment that must be invested at the given rate for the specified number of periods to have the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "返回æ¯ä¸ªå¿…须投资在为指定数é‡çš„时间给率已指定的现值,å¯é€‰çš„未æ¥å€¼ï¼ˆé»˜è®¤0)和支付方å¼ï¼ˆé»˜è®¤å€¼0 =期末,1 =付款金é¢æœŸåˆï¼‰ã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the first value raised to the second value power. "
+msgstr "返回的第一个值æ高到第二个值的力é‡ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the result of multiplying the numeric values. "
+msgstr "返回的数值相乘的结果。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with the first letter of each word converted to uppercase and the others to lowercase. "
+msgstr "返回åŒè½¬æ¢ä¸ºå¤§å†™ï¼Œå…¶ä½™å°å†™æ¯ä¸ªå•è¯é¦–å­—æ¯çš„文本值。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the present value of the given number of payments each invested at the given rate, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). "
+msgstr "返回给定数目的款项的现值æ¯ä¸€ä¸ªç»™å®šçŽ‡çš„投资,å¯é€‰çš„未æ¥å€¼ï¼ˆé»˜è®¤0)和支付方å¼ï¼ˆé»˜è®¤å€¼0 =期末,1 =期åˆï¼‰ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts value in degrees into radians. "
+msgstr "转æ¢ä¸ºå¼§åº¦ï¼Œå­¦ä½çš„价值。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the rate at which the given number of payments each invested at the given rate has the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). "
+msgstr "返回在其中一些款项给æ¯ä¸ªç»™å®šçŽ‡æŠ•èµ„率具有指定的现值,å¯é€‰çš„未æ¥å€¼ï¼ˆé»˜è®¤0)和支付方å¼ï¼ˆé»˜è®¤å€¼0 =期末,1 =期åˆï¼‰ã€‚使用一个åå¤çš„过程,将返回#NUMï¼çš„错误,如果ä¸è¡”接。å¯èƒ½æœ‰å¤šä¸ªå¯èƒ½çš„解决方案。æä¾›å¯é€‰çš„猜测值å¯èƒ½æœ‰åŠ©äºŽæŸäº›æƒ…况下,它ä¸è¡”接或å‘现ä¸æ°å½“的解决方案(默认猜测为10%)。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the specified number of characters starting from the specified position replaced by text2. "
+msgstr "返回åŒç”±Text2中å–代了指定ä½ç½®å¼€å§‹æŒ‡å®šæ•°é‡çš„字符文本1。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text repeated the specified number of times. "
+msgstr "返回的文本é‡å¤æŒ‡å®šçš„次数。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the specified number of characters from the text value starting from the end. If count is omitted, 1 is assumed. "
+msgstr "从文本返回从年底开始值指定数é‡çš„字符。如果罪å被çœç•¥ï¼Œè®¤ä¸ºæ˜¯1。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Rounds the value to the specified number of decimal places. If precision is negative, then round to powers of 10. The default precision is 0 (round to integer). "
+msgstr "回åˆçš„值指定的å°æ•°çš„数字。如果精度为负数,那么到10轮的æƒåŠ›ã€‚默认精度为0(四èˆäº”入到整数)。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the number of rows in the range. "
+msgstr "返回该区域中的行数。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the second portion of a time or date/time value (truncated to an integer). "
+msgstr "返回的时间或日期的第二部分/时间值(å–整)。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric sine function (value is in radians) "
+msgstr "三角正弦函数(值)的弧度"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the amount of depreciation at each period of time using the straight-line method. "
+msgstr "返回在æ¯ä¸€æ¬¡ä½¿ç”¨ç›´çº¿æ³•æœŸé—´çš„折旧é¢ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Square root of the value "
+msgstr "平方根的价值"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample standard deviation of the numeric values. "
+msgstr "返回样本标准差的数值。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the standard deviation of the numeric values. "
+msgstr "返回数值的标准差。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns text1 with the all occurrences of oldtext replaced by newtext. If occurrence is present, then only that occurrence is replaced. "
+msgstr"返回文本1的,是å—到newtextå–代oldtext的所有匹é…项。如果å‘生存在,那么åªæœ‰è¯¥äº‹ä»¶è¢«æ›¿æ¢ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Adds the numeric values. The values to the sum function may be ranges in the form similar to A1:B5. "
+msgstr "添加数值。值函数的款项å¯åœ¨ç±»ä¼¼çš„å½¢å¼ä¸ºA1范围:B5中。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Sums the numeric values of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). If range2 is present, then range1 is tested and the corresponding range2 value is summed. "
+msgstr "求和的å•å…ƒæ ¼åŒºåŸŸçš„数值符åˆæ ‡å‡†ã€‚准则å¯èƒ½æ˜¯ä¸€ä¸ªå€¼ï¼ˆ'×',15,1 3)或测试(25)。若为range2存在,则幅度1-10测试和相应为range2值为总结。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Depreciation by Sum of Year's Digits method. "
+msgstr "按年折旧的ä½æ•°æ€»å’Œæ³•ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value or else a null string. "
+msgstr "返回的文本值,å¦åˆ™ä¸€ä¸ªç©ºå­—符串。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Trigonometric tangent function (value is in radians) "
+msgstr "三角正切函数(值)的弧度"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the time value given the specified hour, minute, and second. "
+msgstr "返回的时间值给指定的å°æ—¶ï¼Œåˆ†é’Ÿå’Œç§’。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the current date (an integer). Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. "
+msgstr "返回当å‰çš„日期(整数)。注:在这个程åºä¸­ï¼Œç¬¬1天是1899å¹´12月31日和1900年是ä¸æ˜¯é—°å¹´ã€‚æŸäº›ç¨‹åºä½¿ç”¨1900å¹´1月1日,作为第1天,并把1900年为闰年年。在这两ç§æƒ…况,ä¸è¿‡ï¼Œæ—¥æˆ–之åŽ00å¹´3月1å·çš„日期,是相åŒçš„。 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with leading, trailing, and repeated spaces removed. "
+msgstr "返回文本值领先,è½åŽï¼Œå¹¶åˆ é™¤é‡å¤çš„空间。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the logical value true. "
+msgstr "返回逻辑值true。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Truncates the value to the specified number of decimal places. If precision is negative, truncate to powers of 10. "
+msgstr "截断的值指定的å°æ•°çš„数字。如果精度是å¦å®šçš„,截断至10çš„æƒåŠ›ã€‚"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the text value with all lowercase characters converted to uppercase. "
+msgstr "返回与转æ¢ä¸ºå¤§å†™å…¨éƒ¨å°å†™çš„文本价值。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Converts the specified text value into a numeric value. Various forms that look like numbers (including digits followed by %, forms that look like dates, etc.) are handled. This may not handle all of the forms accepted by other spreadsheets and may be locale dependent. "
+msgstr "转æ¢ä¸ºæ•°å­—值指定的文本值。å„ç§å½¢å¼ï¼Œåƒï¼ˆåŒ…括%,其次数字,表格,看起æ¥åƒæ—¥æœŸç­‰ï¼‰å¤„ç†æ•°å­—。这ä¸å¾—办ç†å…¶ä»–电å­è¡¨æ ¼æŽ¥å—çš„å„ç§å½¢å¼å’Œå¯èƒ½åœ¨è¯­è¨€çŽ¯å¢ƒè€Œå®šã€‚ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the sample variance of the numeric values. "
+msgstr "返回数值的样本方差。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the variance of the numeric values. "
+msgstr "返回数值的差异。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the column offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match>=value) instead of exact match. "
+msgstr "中查找的范围内给定值的匹é…值,并返回所抵消,在指定的å•å…ƒæ ¼åˆ—相应的值。如果rangelookup为1(默认值),而ä¸æ˜¯0,如果匹é…括å·å†…的数字(匹é…=值)而ä¸æ˜¯å®Œå…¨åŒ¹é…。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the day of week specified by the date value. If type is 1 (the default), Sunday is day and Saturday is day 7. If type is 2, Monday is day 1 and Sunday is day 7. If type is 3, Monday is day 0 and Sunday is day 6. "
+msgstr "返回的日期值指定星期几。如果类型为1(默认),周日一天,是星期六是第7天。如果类型是2,今天是第1天,日是第7天。如果类型为3,星期一是0天,日是第6天。 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Returns the year part of a date value. "
+msgstr "返回日期值一年的一部分。"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value"
+msgstr "价值"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value1, value2, ..."
+msgstr "值1,数值2,..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "valueX, valueY"
+msgstr "valueX,valueY"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "index, value1, value2, ..."
+msgstr "索引,值,数值2,..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range"
+msgstr "范围"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, criteria"
+msgstr "范围,标准"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "year, month, day"
+msgstr "年,月,日"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "databaserange, fieldname, criteriarange"
+msgstr "databaserange,字段å,criteriarange"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period [, factor]"
+msgstr "æˆæœ¬ï¼Œæ®‹å€¼ï¼Œå¯¿å‘½æœŸ[,因å­]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "string1, string2 [, start]"
+msgstr "字符串1,字符串,[开始]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [pv, [paytype]]"
+msgstr "率,氮,付款,[å¶æž¯ç—…,[paytype]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, row, [rangelookup]"
+msgstr "值,范围,行,[rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "logical-expression, true-value, false-value"
+msgstr "逻辑表达,真值,å‡å€¼"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, rownum, colnum"
+msgstr "范围,ROWNUM给出,colnum"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range, [guess]"
+msgstr "范围,[猜想]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, count"
+msgstr "文本,伯爵"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, base"
+msgstr "价值,基地"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, [rangelookup]"
+msgstr "值,范围,[rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text, start, length"
+msgstr "文本,开始,长度"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, payment, pv, [fv, [paytype]]"
+msgstr "率,付款,光ä¼ï¼Œ[抗体,[paytype]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, value1, value2, ..."
+msgstr "率,值1,数值2,..."
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, pv, [fv, [paytype]]"
+msgstr "率,氮,病èŒï¼Œ[抗体,[paytype]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "rate, n, payment, [fv, [paytype]]"
+msgstr "率,氮,付款,[抗体,[paytype]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "n, payment, pv, [fv, [paytype, [guess]]]"
+msgstr "北,付款,光ä¼ï¼Œ[抗体,[paytype,[猜想]]]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, start, length, text2"
+msgstr "文本1,开始,长度,Text2中"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, [precision]"
+msgstr "值,[精度]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime"
+msgstr "æˆæœ¬ï¼Œæ®‹å€¼ï¼Œå¯¿å‘½"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "cost, salvage, lifetime, period"
+msgstr "æˆæœ¬ï¼Œæ®‹å€¼ï¼Œå¯¿å‘½æœŸ"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "text1, oldtext, newtext [, occurrence]"
+msgstr "文本1,oldtext,newtext [,出现的]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "range1, criteria [, range2]"
+msgstr "为range1,标准[,为range2]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "hour, minute, second"
+msgstr "å°æ—¶ï¼Œåˆ†ï¼Œç§’"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "value, range, col, [rangelookup]"
+msgstr "值,范围,山å£ï¼Œ[rangelookup]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date, [type]"
+msgstr "到目å‰ä¸ºæ­¢ï¼Œ[类型]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "date"
+msgstr "日期"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+#msgid ["all", "stat", "lookup", "datetime", "financial", "test", "math", Text]
+#msgstr ["所有","统计","查找","日期","财务","测试","数学",文字]
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "All"
+msgstr "全部"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Statistics"
+msgstr "统计"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Lookup"
+msgstr "查找"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Date & Time"
+msgstr "日期和时间"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Financial"
+msgstr "è´¢ç»"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Test"
+msgstr "测试"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Math"
+msgstr "æ•°å­¦"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Cells to Graph"
+msgstr "细胞对图"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Set Cells To Graph"
+msgstr "设置å•å…ƒæ ¼å›¾"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph Type"
+msgstr "图表类型"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "filter:alpha(opacity=90);opacity:.9;"
+msgstr "过滤器:α(ä¸é€æ˜Žåº¦= 90);混浊:.9;"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plain"
+msgstr "平原"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Graph"
+msgstr "图"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Pie Chart"
+msgstr "饼图"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Help"
+msgstr "帮助"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Horizontal Bar"
+msgstr "å•æ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Vertical Bar"
+msgstr "åž‚ç›´æ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Line Chart"
+msgstr "线路图"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Plot Points"
+msgstr "情节点"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Unknown range name"
+msgstr "未知的范围å称"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Hide Help"
+msgstr "éšè—帮助r"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Max "
+msgstr "最大 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "Min "
+msgstr "æ°‘ "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid " OK "
+msgstr " 确定 "
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "[Cancel]"
+msgstr "[å–消]"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "TRUE"
+msgstr "真"
+
+#: /home/olpc/Activities/SocialCalcActivity.activity/localized_strings_file.py:
+msgid "FALSE"
+msgstr "å‡"
+
diff --git a/result.py b/result.py
new file mode 100644
index 0000000..a43b67a
--- /dev/null
+++ b/result.py
@@ -0,0 +1,25 @@
+# Copyright (c) 2008, Media Modifications Ltd.
+
+#Permission is hereby granted, free of charge, to any person obtaining a copy
+#of this software and associated documentation files (the "Software"), to deal
+#in the Software without restriction, including without limitation the rights
+#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+#copies of the Software, and to permit persons to whom the Software is
+#furnished to do so, subject to the following conditions:
+
+#The above copyright notice and this permission notice shall be included in
+#all copies or substantial portions of the Software.
+
+#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+#THE SOFTWARE.
+
+
+class ServerResult:
+ def __init__(self):
+ self.txt = ""
+ self.headers = [] \ No newline at end of file
diff --git a/server.py b/server.py
new file mode 100644
index 0000000..9a91ad4
--- /dev/null
+++ b/server.py
@@ -0,0 +1,69 @@
+# Copyright (c) 2008, Media Modifications Ltd.
+
+#Permission is hereby granted, free of charge, to any person obtaining a copy
+#of this software and associated documentation files (the "Software"), to deal
+#in the Software without restriction, including without limitation the rights
+#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+#copies of the Software, and to permit persons to whom the Software is
+#furnished to do so, subject to the following conditions:
+
+#The above copyright notice and this permission notice shall be included in
+#all copies or substantial portions of the Software.
+
+#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+#THE SOFTWARE.
+
+
+import urlparse
+import urllib
+import posixpath
+import SimpleHTTPServer
+import BaseHTTPServer
+
+
+class Server(BaseHTTPServer.HTTPServer):
+ def __init__(self, server_address, logic):
+ BaseHTTPServer.HTTPServer.__init__(self, server_address, RegHandler)
+ self.logic = logic
+
+
+#RegHandler extends SimpleHTTPServer.py (in python 2.4)
+class RegHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
+ def do_POST( self ):
+ self.translate_path()
+
+
+ def do_GET( self ):
+ self.translate_path()
+
+
+ def do_HEAD( self ):
+ self.translate_path()
+
+
+ def translate_path(self):
+ #todo: compare with send_head in parent
+ urlp = urlparse.urlparse(self.path)
+
+ urls = urlp[2]
+ urls = posixpath.normpath(urllib.unquote(urls))
+ urlPath = urls.split('/')
+ urlPath = filter(None, urlPath)
+
+ params = urlp[4]
+ parama = []
+ allParams = params.split('&')
+ for i in range (0, len(allParams)):
+ parama.append(allParams[i].split('='))
+
+ result = self.server.logic.doServerLogic(self.path, urlPath, parama)
+ self.send_response(200)
+ for i in range (0, len(result.headers)):
+ self.send_header( result.headers[i][0], result.headers[i][1] )
+ self.end_headers()
+ self.wfile.write( result.txt ) \ No newline at end of file
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..c9079fc
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,18 @@
+#!/usr/bin/python
+
+# Make the MANIFEST file. The contents of the activity folder and the NEWS and MANIFEST
+# files are already included in the .xo file which the bundlebuilder creates, so don't
+# add them to the manifest file.
+import os
+##os.system("find ./ -name 'activity' -prune -o -name 'NEWS' \
+## -prune -o -name 'MANIFEST' \
+## -prune -o -name '.svn' \
+## -prune -o -name '*.pyc' \
+## -prune -o -name '*.xo' \
+## -prune -o -name '*.swp' \
+## -prune -o -name '.git*' \
+## -prune -o -type f \
+## -print > MANIFEST")
+
+from sugar.activity import bundlebuilder
+bundlebuilder.start("SocialCalcActivity")
diff --git a/test-web-view.py b/test-web-view.py
new file mode 100644
index 0000000..ee4676c
--- /dev/null
+++ b/test-web-view.py
@@ -0,0 +1,45 @@
+import os
+import gtk
+import time
+import hulahop
+hulahop.startup(os.path.expanduser('~/.test-hulahop'))
+from XOCom import XOCom
+
+# The XOCom object helps us communicate with the browser
+uri = "file:///home/olpc/src/socialcalc-xocom/web/index.html"
+xocom = XOCom(uri)
+
+# This is just a simple way to trigger events from python for testing
+# Handler for keypresses in the GTK Application
+# r - call the javascript 'read' hook with a dummy string
+# w - call the javascript 'write' hook and print out the result
+def keypress(window, event):
+ key = event.string
+ if key == 'w':
+ result = xocom.send_to_browser('write')
+ if result:
+ print "Result from browser - '%s'"%result
+ else:
+ print "No data received in the browser's response"
+ if key == 'r':
+ message = "I am a monkey - %s"%time.time()
+ print "Sending '%s'"%message
+ result = xocom.send_to_browser('read', message)
+ if key == 'q':
+ quit(None)
+
+
+# Shut down our app
+def quit(window):
+# hulahop.shutdown()
+ gtk.main_quit()
+
+# Create our GTK window containing the embedded browser, and hook up some handlers
+window = gtk.Window()
+window.set_default_size(600, 400)
+window.connect("destroy", quit)
+window.connect("key_press_event", keypress)
+
+window.add( xocom.create_webview() )
+window.show()
+gtk.main()
diff --git a/todo b/todo
new file mode 100644
index 0000000..7501316
--- /dev/null
+++ b/todo
@@ -0,0 +1,6 @@
+* Introducing multi-user editing, via visualizing peer's e-cells with colored borders.
+* Proper sharing of graphs over the mesh network.
+* Creating the infrastructure to support multi-sheet editing. Primarily, required to open and edit .wk4 and .xls workbooks having multiple worksheets.
+* Improving the interoperability with lotus .wk4 and excel .xls
+* To develop interoperability of socialcalc with other file formats like csv, open-office etc.
+* To improve the localization infrasture and localizing it in many more languages. \ No newline at end of file
diff --git a/web/formatnumber2.js b/web/formatnumber2.js
new file mode 100644
index 0000000..a84176c
--- /dev/null
+++ b/web/formatnumber2.js
@@ -0,0 +1,950 @@
+//
+/*
+// SocialCalc Number Formatting Library
+//
+// Part of the SocialCalc package.
+//
+// (c) Copyright 2008 Socialtext, Inc.
+// All Rights Reserved.
+//
+// The contents of this file are subject to the Artistic License 2.0; you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at http://socialcalc.org/licenses/al-20/.
+//
+// Some of the other files in the SocialCalc package are licensed under
+// different licenses. Please note the licenses of the modules you use.
+//
+// Code History:
+//
+// Initially coded by Dan Bricklin of Software Garden, Inc., for Socialtext, Inc.
+// Based in part on the SocialCalc 1.1.0 code written in Perl.
+// The SocialCalc 1.1.0 code was:
+// Portions (c) Copyright 2005, 2006, 2007 Software Garden, Inc.
+// All Rights Reserved.
+// Portions (c) Copyright 2007 Socialtext, Inc.
+// All Rights Reserved.
+// The Perl SocialCalc started as modifications to the wikiCalc(R) program, version 1.0.
+// wikiCalc 1.0 was written by Software Garden, Inc.
+// Unless otherwise specified, referring to "SocialCalc" in comments refers to this
+// JavaScript version of the code, not the SocialCalc Perl code.
+//
+*/
+
+ var SocialCalc;
+ if (!SocialCalc) SocialCalc = {}; // May be used with other SocialCalc libraries or standalone
+
+SocialCalc.FormatNumber = {};
+
+SocialCalc.FormatNumber.format_definitions = {}; // Parsed formats are stored here globally
+
+// Most constants that are often customized for localization are in the SocialCalc.Constants module.
+// If you use this module standalone, provide at least the "FormatNumber" values.
+//
+
+// The following values may be customized externally for further localization of the format definitions themselves,
+// but that would make them incompatible with other uses and is discouraged.
+//
+
+SocialCalc.FormatNumber.separatorchar = ",";
+SocialCalc.FormatNumber.decimalchar = ".";
+SocialCalc.FormatNumber.daynames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
+SocialCalc.FormatNumber.daynames3 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
+SocialCalc.FormatNumber.monthnames3 = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
+SocialCalc.FormatNumber.monthnames = ["January", "February", "March", "April", "May", "June", "July", "August", "September",
+ "October", "November", "December"];
+
+SocialCalc.FormatNumber.allowedcolors =
+ {BLACK: "#000000", BLUE: "#0000FF", CYAN: "#00FFFF", GREEN: "#00FF00", MAGENTA: "#FF00FF",
+ RED: "#FF0000", WHITE: "#FFFFFF", YELLOW: "#FFFF00"};
+
+SocialCalc.FormatNumber.alloweddates =
+ {H: "h]", M: "m]", MM: "mm]", S: "s]", SS: "ss]"};
+
+// Other constants
+
+SocialCalc.FormatNumber.commands =
+ {copy: 1, color: 2, integer_placeholder: 3, fraction_placeholder: 4, decimal: 5,
+ currency: 6, general:7, separator: 8, date: 9, comparison: 10, section: 11, style: 12};
+
+SocialCalc.FormatNumber.datevalues = {julian_offset: 2415019, seconds_in_a_day: 24 * 60 * 60, seconds_in_an_hour: 60 * 60};
+
+/* *******************
+
+ result = SocialCalc.FormatNumber.formatNumberWithFormat = function(rawvalue, format_string, currency_char)
+
+************************* */
+
+SocialCalc.FormatNumber.formatNumberWithFormat = function(rawvalue, format_string, currency_char) {
+
+ var scc = SocialCalc.Constants;
+ var scfn = SocialCalc.FormatNumber;
+
+ var op, operandstr, fromend, cval, operandstrlc;
+ var startval, estartval;
+ var hrs, mins, secs, ehrs, emins, esecs, ampmstr, ymd;
+ var minOK, mpos;
+ var result="";
+ var thisformat;
+ var section, gotcomparison, compop, compval, cpos, oppos;
+ var sectioninfo;
+ var i, decimalscale, scaledvalue, strvalue, strparts, integervalue, fractionvalue;
+ var integerdigits2, integerpos, fractionpos, textcolor, textstyle, separatorchar, decimalchar;
+ var value; // working copy to change sign, etc.
+
+ rawvalue = rawvalue-0; // make sure a number
+ value = rawvalue;
+ if (!isFinite(value)) return "NaN";
+
+ var negativevalue = value < 0 ? 1 : 0; // determine sign, etc.
+ if (negativevalue) value = -value;
+ var zerovalue = value == 0 ? 1 : 0;
+
+ currency_char = currency_char || scc.FormatNumber_DefaultCurrency;
+
+ scfn.parse_format_string(scfn.format_definitions, format_string); // make sure format is parsed
+ thisformat = scfn.format_definitions[format_string]; // Get format structure
+
+ if (!thisformat) throw "Format not parsed error!";
+
+ section = thisformat.sectioninfo.length - 1; // get number of sections - 1
+
+ if (thisformat.hascomparison) { // has comparisons - determine which section
+ section = 0; // set to which section we will use
+ gotcomparison = 0; // this section has no comparison
+ for (cpos=0; ;cpos++) { // scan for comparisons
+ op = thisformat.operators[cpos];
+ operandstr = thisformat.operands[cpos]; // get next operator and operand
+ if (!op) { // at end with no match
+ if (gotcomparison) { // if comparison but no match
+ format_string = "General"; // use default of General
+ scfn.parse_format_string(scfn.format_definitions, format_string);
+ thisformat = scfn.format_definitions[format_string];
+ section = 0;
+ }
+ break; // if no comparision, matches on this section
+ }
+ if (op == scfn.commands.section) { // end of section
+ if (!gotcomparison) { // no comparison, so it's a match
+ break;
+ }
+ gotcomparison = 0;
+ section++; // check out next one
+ continue;
+ }
+ if (op == scfn.commands.comparison) { // found a comparison - do we meet it?
+ i=operandstr.indexOf(":");
+ compop=operandstr.substring(0,i);
+ compval=operandstr.substring(i+1)-0;
+ if ((compop == "<" && rawvalue < compval) ||
+ (compop == "<=" && rawvalue <= compval) ||
+ (compop == "=" && rawvalue == compval) ||
+ (compop == "<>" && rawvalue != compval) ||
+ (compop == ">=" && rawvalue >= compval) ||
+ (compop == ">" && rawvalue > compval)) { // a match
+ break;
+ }
+ gotcomparison = 1;
+ }
+ }
+ }
+ else if (section > 0) { // more than one section (separated by ";")
+ if (section == 1) { // two sections
+ if (negativevalue) {
+ negativevalue = 0; // sign will provided by section, not automatically
+ section = 1; // use second section for negative values
+ }
+ else {
+ section = 0; // use first for all others
+ }
+ }
+ else if (section == 2) { // three sections
+ if (negativevalue) {
+ negativevalue = 0; // sign will provided by section, not automatically
+ section = 1; // use second section for negative values
+ }
+ else if (zerovalue) {
+ section = 2; // use third section for zero values
+ }
+ else {
+ section = 0; // use first for positive
+ }
+ }
+ }
+
+ sectioninfo = thisformat.sectioninfo[section]; // look at values for our section
+
+ if (sectioninfo.commas > 0) { // scale by thousands
+ for (i=0; i<sectioninfo.commas; i++) {
+ value /= 1000;
+ }
+ }
+ if (sectioninfo.percent > 0) { // do percent scaling
+ for (i=0; i<sectioninfo.percent; i++) {
+ value *= 100;
+ }
+ }
+
+ decimalscale = 1; // cut down to required number of decimal digits
+ for (i=0; i<sectioninfo.fractiondigits; i++) {
+ decimalscale *= 10;
+ }
+ scaledvalue = Math.floor(value * decimalscale + 0.5);
+ scaledvalue = scaledvalue / decimalscale;
+
+ if (typeof scaledvalue != "number") return "NaN";
+ if (!isFinite(scaledvalue)) return "NaN";
+
+ strvalue = scaledvalue+""; // convert to string (Number.toFixed doesn't do all we need)
+
+// strvalue = value.toFixed(sectioninfo.fractiondigits); // cut down to required number of decimal digits
+ // and convert to string
+
+ if (scaledvalue == 0 && (sectioninfo.fractiondigits || sectioninfo.integerdigits)) {
+ negativevalue = 0; // no "-0" unless using multiple sections or General
+ }
+
+ if (strvalue.indexOf("e")>=0) { // converted to scientific notation
+ return rawvalue+""; // Just return plain converted raw value
+ }
+
+ strparts=strvalue.match(/^\+{0,1}(\d*)(?:\.(\d*)){0,1}$/); // get integer and fraction parts
+ if (!strparts) return "NaN"; // if not a number
+ integervalue = strparts[1];
+ if (!integervalue || integervalue=="0") integervalue="";
+ fractionvalue = strparts[2];
+ if (!fractionvalue) fractionvalue = "";
+
+ if (sectioninfo.hasdate) { // there are date placeholders
+ if (rawvalue < 0) { // bad date
+ return "??-???-??&nbsp;??:??:??";
+ }
+ startval = (rawvalue-Math.floor(rawvalue)) * scfn.datevalues.seconds_in_a_day; // get date/time parts
+ estartval = rawvalue * scfn.datevalues.seconds_in_a_day; // do elapsed time version, too
+ hrs = Math.floor(startval / scfn.datevalues.seconds_in_an_hour);
+ ehrs = Math.floor(estartval / scfn.datevalues.seconds_in_an_hour);
+ startval = startval - hrs * scfn.datevalues.seconds_in_an_hour;
+ mins = Math.floor(startval / 60);
+ emins = Math.floor(estartval / 60);
+ secs = startval - mins * 60;
+ decimalscale = 1; // round appropriately depending if there is ss.0
+ for (i=0; i<sectioninfo.fractiondigits; i++) {
+ decimalscale *= 10;
+ }
+ secs = Math.floor(secs * decimalscale + 0.5);
+ secs = secs / decimalscale;
+ esecs = Math.floor(estartval * decimalscale + 0.5);
+ esecs = esecs / decimalscale;
+ if (secs >= 60) { // handle round up into next second, minute, etc.
+ secs = 0;
+ mins++; emins++;
+ if (mins >= 60) {
+ mins = 0;
+ hrs++; ehrs++;
+ if (hrs >= 24) {
+ hrs = 0;
+ rawvalue++;
+ }
+ }
+ }
+ fractionvalue = (secs-Math.floor(secs))+""; // for "hh:mm:ss.000"
+ fractionvalue = fractionvalue.substring(2); // skip "0."
+
+ ymd = SocialCalc.FormatNumber.convert_date_julian_to_gregorian(Math.floor(rawvalue+scfn.datevalues.julian_offset));
+
+ minOK; // says "m" can be minutes
+ mspos = sectioninfo.sectionstart; // m scan position in ops
+ for ( ; ; mspos++) { // scan for "m" and "mm" to see if any minutes fields, and am/pm
+ op = thisformat.operators[mspos];
+ operandstr = thisformat.operands[mspos]; // get next operator and operand
+ if (!op) break; // don't go past end
+ if (op==scfn.commands.section) break;
+ if (op==scfn.commands.date) {
+ if ((operandstr.toLowerCase()=="am/pm" || operandstr.toLowerCase()=="a/p") && !ampmstr) {
+ if (hrs >= 12) {
+ hrs -= 12;
+ ampmstr = operandstr.toLowerCase()=="a/p" ? scc.s_FormatNumber_pm1 : scc.s_FormatNumber_pm; // "P" : "PM";
+ }
+ else {
+ ampmstr = operandstr.toLowerCase()=="a/p" ? scc.s_FormatNumber_am1 : scc.s_FormatNumber_am; // "A" : "AM";
+ }
+ if (operandstr.indexOf(ampmstr)<0)
+ ampmstr = ampmstr.toLowerCase(); // have case match case in format
+ }
+ if (minOK && (operandstr=="m" || operandstr=="mm")) {
+ thisformat.operands[mspos] += "in"; // turn into "min" or "mmin"
+ }
+ if (operandstr.charAt(0)=="h") {
+ minOK = 1; // m following h or hh or [h] is minutes not months
+ }
+ else {
+ minOK = 0;
+ }
+ }
+ else if (op!=scfn.commands.copy) { // copying chars can be between h and m
+ minOK = 0;
+ }
+ }
+ minOK = 0;
+ for (--mspos; ; mspos--) { // scan other way for s after m
+ op = thisformat.operators[mspos];
+ operandstr = thisformat.operands[mspos]; // get next operator and operand
+ if (!op) break; // don't go past end
+ if (op==scfn.commands.section) break;
+ if (op==scfn.commands.date) {
+ if (minOK && (operandstr=="m" || operandstr=="mm")) {
+ thisformat.operands[mspos] += "in"; // turn into "min" or "mmin"
+ }
+ if (operandstr=="ss") {
+ minOK = 1; // m before ss is minutes not months
+ }
+ else {
+ minOK = 0;
+ }
+ }
+ else if (op!=scfn.commands.copy) { // copying chars can be between ss and m
+ minOK = 0;
+ }
+ }
+ }
+
+ integerdigits2 = 0; // init counters, etc.
+ integerpos = 0;
+ fractionpos = 0;
+ textcolor = "";
+ textstyle = "";
+ separatorchar = scc.FormatNumber_separatorchar;
+ if (separatorchar.indexOf(" ")>=0) separatorchar = separatorchar.replace(/ /g, "&nbsp;");
+ decimalchar = scc.FormatNumber_decimalchar;
+ if (decimalchar.indexOf(" ")>=0) decimalchar = decimalchar.replace(/ /g, "&nbsp;");
+
+ oppos = sectioninfo.sectionstart;
+
+ while (op = thisformat.operators[oppos]) { // execute format
+ operandstr = thisformat.operands[oppos++]; // get next operator and operand
+
+ if (op == scfn.commands.copy) { // put char in result
+ result += operandstr;
+ }
+
+ else if (op == scfn.commands.color) { // set color
+ textcolor = operandstr;
+ }
+
+ else if (op == scfn.commands.style) { // set style
+ textstyle = operandstr;
+ }
+
+ else if (op == scfn.commands.integer_placeholder) { // insert number part
+ if (negativevalue) {
+ result += "-";
+ negativevalue = 0;
+ }
+ integerdigits2++;
+ if (integerdigits2 == 1) { // first one
+ if (integervalue.length > sectioninfo.integerdigits) { // see if integer wider than field
+ for (;integerpos < (integervalue.length - sectioninfo.integerdigits); integerpos++) {
+ result += integervalue.charAt(integerpos);
+ if (sectioninfo.thousandssep) { // see if this is a separator position
+ fromend = integervalue.length - integerpos - 1;
+ if (fromend > 2 && fromend % 3 == 0) {
+ result += separatorchar;
+ }
+ }
+ }
+ }
+ }
+ if (integervalue.length < sectioninfo.integerdigits
+ && integerdigits2 <= sectioninfo.integerdigits - integervalue.length) { // field is wider than value
+ if (operandstr == "0" || operandstr == "?") { // fill with appropriate characters
+ result += operandstr == "0" ? "0" : "&nbsp;";
+ if (sectioninfo.thousandssep) { // see if this is a separator position
+ fromend = sectioninfo.integerdigits - integerdigits2;
+ if (fromend > 2 && fromend % 3 == 0) {
+ result += separatorchar;
+ }
+ }
+ }
+ }
+ else { // normal integer digit - add it
+ result += integervalue.charAt(integerpos);
+ if (sectioninfo.thousandssep) { // see if this is a separator position
+ fromend = integervalue.length - integerpos - 1;
+ if (fromend > 2 && fromend % 3 == 0) {
+ result += separatorchar;
+ }
+ }
+ integerpos++;
+ }
+ }
+ else if (op == scfn.commands.fraction_placeholder) { // add fraction part of number
+ if (fractionpos >= fractionvalue.length) {
+ if (operandstr == "0" || operandstr == "?") {
+ result += operandstr == "0" ? "0" : "&nbsp;";
+ }
+ }
+ else {
+ result += fractionvalue.charAt(fractionpos);
+ }
+ fractionpos++;
+ }
+
+ else if (op == scfn.commands.decimal) { // decimal point
+ if (negativevalue) {
+ result += "-";
+ negativevalue = 0;
+ }
+ result += decimalchar;
+ }
+
+ else if (op == scfn.commands.currency) { // currency symbol
+ if (negativevalue) {
+ result += "-";
+ negativevalue = 0;
+ }
+ result += operandstr;
+ }
+
+ else if (op == scfn.commands.general) { // insert "General" conversion
+
+ // *** Cut down number of significant digits to avoid floating point artifacts:
+
+ if (value!=0) { // only if non-zero
+ var factor = Math.floor(Math.LOG10E * Math.log(value)); // get integer magnitude as a power of 10
+ factor = Math.pow(10, 13-factor); // turn into scaling factor
+ value = Math.floor(factor * value + 0.5)/factor; // scale positive value, round, undo scaling
+ if (!isFinite(value)) return "NaN";
+ }
+ if (negativevalue) {
+ result += "-";
+ }
+ strvalue = value+""; // convert original value to string
+ if (strvalue.indexOf("e")>=0) { // converted to scientific notation
+ result += strvalue;
+ continue;
+ }
+ strparts=strvalue.match(/^\+{0,1}(\d*)(?:\.(\d*)){0,1}$/); // get integer and fraction parts
+ integervalue = strparts[1];
+ if (!integervalue || integervalue=="0") integervalue="";
+ fractionvalue = strparts[2];
+ if (!fractionvalue) fractionvalue = "";
+ integerpos = 0;
+ fractionpos = 0;
+ if (integervalue.length) {
+ for (;integerpos < integervalue.length; integerpos++) {
+ result += integervalue.charAt(integerpos);
+ if (sectioninfo.thousandssep) { // see if this is a separator position
+ fromend = integervalue.length - integerpos - 1;
+ if (fromend > 2 && fromend % 3 == 0) {
+ result += separatorchar;
+ }
+ }
+ }
+ }
+ else {
+ result += "0";
+ }
+ if (fractionvalue.length) {
+ result += decimalchar;
+ for (;fractionpos < fractionvalue.length; fractionpos++) {
+ result += fractionvalue.charAt(fractionpos);
+ }
+ }
+ }
+ else if (op==scfn.commands.date) { // date placeholder
+ operandstrlc = operandstr.toLowerCase();
+ if (operandstrlc=="y" || operandstrlc=="yy") {
+ result += (ymd.year+"").substring(2);
+ }
+ else if (operandstrlc=="yyyy") {
+ result += ymd.year+"";
+ }
+ else if (operandstrlc=="d") {
+ result += ymd.day+"";
+ }
+ else if (operandstrlc=="dd") {
+ cval = 1000 + ymd.day;
+ result += (cval+"").substr(2);
+ }
+ else if (operandstrlc=="ddd") {
+ cval = Math.floor(rawvalue+6) % 7;
+ result += scc.s_FormatNumber_daynames3[cval];
+ }
+ else if (operandstrlc=="dddd") {
+ cval = Math.floor(rawvalue+6) % 7;
+ result += scc.s_FormatNumber_daynames[cval];
+ }
+ else if (operandstrlc=="m") {
+ result += ymd.month+"";
+ }
+ else if (operandstrlc=="mm") {
+ cval = 1000 + ymd.month;
+ result += (cval+"").substr(2);
+ }
+ else if (operandstrlc=="mmm") {
+ result += scc.s_FormatNumber_monthnames3[ymd.month-1];
+ }
+ else if (operandstrlc=="mmmm") {
+ result += scc.s_FormatNumber_monthnames[ymd.month-1];
+ }
+ else if (operandstrlc=="mmmmm") {
+ result += scc.s_FormatNumber_monthnames[ymd.month-1].charAt(0);
+ }
+ else if (operandstrlc=="h") {
+ result += hrs+"";
+ }
+ else if (operandstrlc=="h]") {
+ result += ehrs+"";
+ }
+ else if (operandstrlc=="mmin") {
+ cval = (1000 + mins)+"";
+ result += cval.substr(2);
+ }
+ else if (operandstrlc=="mm]") {
+ if (emins < 100) {
+ cval = (1000 + emins)+"";
+ result += cval.substr(2);
+ }
+ else {
+ result += emins+"";
+ }
+ }
+ else if (operandstrlc=="min") {
+ result += mins+"";
+ }
+ else if (operandstrlc=="m]") {
+ result += emins+"";
+ }
+ else if (operandstrlc=="hh") {
+ cval = (1000 + hrs)+"";
+ result += cval.substr(2);
+ }
+ else if (operandstrlc=="s") {
+ cval = Math.floor(secs);
+ result += cval+"";
+ }
+ else if (operandstrlc=="ss") {
+ cval = (1000 + Math.floor(secs))+"";
+ result += cval.substr(2);
+ }
+ else if (operandstrlc=="am/pm" || operandstrlc=="a/p") {
+ result += ampmstr;
+ }
+ else if (operandstrlc=="ss]") {
+ if (esecs < 100) {
+ cval = (1000 + Math.floor(esecs))+"";
+ result += cval.substr(2);
+ }
+ else {
+ cval = Math.floor(esecs);
+ result += cval+"";
+ }
+ }
+ }
+ else if (op == scfn.commands.section) { // end of section
+ break;
+ }
+
+ else if (op == scfn.commands.comparison) { // ignore
+ continue;
+ }
+
+ else {
+ result += "!! Parse error !!";
+ }
+ }
+
+ if (textcolor) {
+ result = '<span style="color:'+textcolor+';">'+result+'</span>';
+ }
+ if (textstyle) {
+ result = '<span style="'+textstyle+';">'+result+'</span>';
+ }
+
+ return result;
+
+ };
+
+/* *******************
+
+ SocialCalc.FormatNumber.parse_format_string(format_defs, format_string)
+
+ Takes a format string (e.g., "#,##0.00_);(#,##0.00)") and fills in format_defs with the parsed info
+
+ format_defs
+ ["#,##0.0"]->{} - elements in the hash are one hash for each format
+ .operators->[] - array of operators from parsing the format string (each a number)
+ .operands->[] - array of corresponding operators (each usually a string)
+ .sectioninfo->[] - one hash for each section of the format
+ .start
+ .integerdigits
+ .fractiondigits
+ .commas
+ .percent
+ .thousandssep
+ .hasdates
+ .hascomparison - true if any section has [<100], etc.
+
+************************* */
+
+SocialCalc.FormatNumber.parse_format_string = function(format_defs, format_string) {
+
+ var scfn = SocialCalc.FormatNumber;
+
+ var thisformat, section, sectionfinfo;
+ var integerpart = 1; // start out in integer part
+ var lastwasinteger; // last char was an integer placeholder
+ var lastwasslash; // last char was a backslash - escaping following character
+ var lastwasasterisk; // repeat next char
+ var lastwasunderscore; // last char was _ which picks up following char for width
+ var inquote, quotestr; // processing a quoted string
+ var inbracket, bracketstr, bracketdata; // processing a bracketed string
+ var ingeneral, gpos; // checks for characters "General"
+ var ampmstr, part; // checks for characters "A/P" and "AM/PM"
+ var indate; // keeps track of date/time placeholders
+ var chpos; // character position being looked at
+ var ch; // character being looked at
+
+ if (format_defs[format_string]) return; // already defined - nothing to do
+
+ thisformat = {operators: [], operands: [], sectioninfo: [{}]}; // create info structure for this format
+ format_defs[format_string] = thisformat; // add to other format definitions
+
+ section = 0; // start with section 0
+ sectioninfo = thisformat.sectioninfo[section]; // get reference to info for current section
+ sectioninfo.sectionstart = 0; // position in operands that starts this section
+ sectioninfo.integerdigits = 0; // number of integer-part placeholders
+ sectioninfo.fractiondigits = 0; // fraction placeholders
+ sectioninfo.commas = 0; // commas encountered, to handle scaling
+ sectioninfo.percent = 0; // times to scale by 100
+
+ for (chpos=0; chpos<format_string.length; chpos++) { // parse
+ ch = format_string.charAt(chpos); // get next char to examine
+ if (inquote) {
+ if (ch == '"') {
+ inquote = 0;
+ thisformat.operators.push(scfn.commands.copy);
+ thisformat.operands.push(quotestr);
+ continue;
+ }
+ quotestr += ch;
+ continue;
+ }
+ if (inbracket) {
+ if (ch==']') {
+ inbracket = 0;
+ bracketdata=SocialCalc.FormatNumber.parse_format_bracket(bracketstr);
+ if (bracketdata.operator==scfn.commands.separator) {
+ sectioninfo.thousandssep = 1; // explicit [,]
+ continue;
+ }
+ if (bracketdata.operator==scfn.commands.date) {
+ sectioninfo.hasdate = 1;
+ }
+ if (bracketdata.operator==scfn.commands.comparison) {
+ thisformat.hascomparison = 1;
+ }
+ thisformat.operators.push(bracketdata.operator);
+ thisformat.operands.push(bracketdata.operand);
+ continue;
+ }
+ bracketstr += ch;
+ continue;
+ }
+ if (lastwasslash) {
+ thisformat.operators.push(scfn.commands.copy);
+ thisformat.operands.push(ch);
+ lastwasslash=false;
+ continue;
+ }
+ if (lastwasasterisk) {
+ thisformat.operators.push(scfn.commands.copy);
+ thisformat.operands.push(ch+ch+ch+ch+ch); // do 5 of them since no real tabs
+ lastwasasterisk=false;
+ continue;
+ }
+ if (lastwasunderscore) {
+ thisformat.operators.push(scfn.commands.copy);
+ thisformat.operands.push("&nbsp;");
+ lastwasunderscore=false;
+ continue;
+ }
+ if (ingeneral) {
+ if ("general".charAt(ingeneral)==ch.toLowerCase()) {
+ ingeneral++;
+ if (ingeneral == 7) {
+ thisformat.operators.push(scfn.commands.general);
+ thisformat.operands.push(ch);
+ ingeneral=0;
+ }
+ continue;
+ }
+ ingeneral = 0;
+ }
+ if (indate) { // last char was part of a date placeholder
+ if (indate.charAt(0)==ch) { // another of the same char
+ indate += ch; // accumulate it
+ continue;
+ }
+ thisformat.operators.push(scfn.commands.date); // something else, save date info
+ thisformat.operands.push(indate);
+ sectioninfo.hasdate=1;
+ indate = "";
+ }
+ if (ampmstr) {
+ ampmstr += ch;
+ part=ampmstr.toLowerCase();
+ if (part!="am/pm".substring(0,part.length) && part!="a/p".substring(0,part.length)) {
+ ampstr="";
+ }
+ else if (part=="am/pm" || part=="a/p") {
+ thisformat.operators.push(scfn.commands.date);
+ thisformat.operands.push(ampmstr);
+ ampmstr = "";
+ }
+ continue;
+ }
+ if (ch=="#" || ch=="0" || ch=="?") { // placeholder
+ if (integerpart) {
+ sectioninfo.integerdigits++;
+ if (sectioninfo.commas) { // comma inside of integer placeholders
+ sectioninfo.thousandssep = 1; // any number is thousands separator
+ sectioninfo.commas = 0; // reset count of "thousand" factors
+ }
+ lastwasinteger = 1;
+ thisformat.operators.push(scfn.commands.integer_placeholder);
+ thisformat.operands.push(ch);
+ }
+ else {
+ sectioninfo.fractiondigits++;
+ thisformat.operators.push(scfn.commands.fraction_placeholder);
+ thisformat.operands.push(ch);
+ }
+ }
+ else if (ch==".") { // decimal point
+ lastwasinteger = 0;
+ thisformat.operators.push(scfn.commands.decimal);
+ thisformat.operands.push(ch);
+ integerpart = 0;
+ }
+ else if (ch=='$') { // currency char
+ lastwasinteger = 0;
+ thisformat.operators.push(scfn.commands.currency);
+ thisformat.operands.push(ch);
+ }
+ else if (ch==",") {
+ if (lastwasinteger) {
+ sectioninfo.commas++;
+ }
+ else {
+ thisformat.operators.push(scfn.commands.copy);
+ thisformat.operands.push(ch);
+ }
+ }
+ else if (ch=="%") {
+ lastwasinteger = 0;
+ sectioninfo.percent++;
+ thisformat.operators.push(scfn.commands.copy);
+ thisformat.operands.push(ch);
+ }
+ else if (ch=='"') {
+ lastwasinteger = 0;
+ inquote = 1;
+ quotestr = "";
+ }
+ else if (ch=='[') {
+ lastwasinteger = 0;
+ inbracket = 1;
+ bracketstr = "";
+ }
+ else if (ch=='\\') {
+ lastwasslash = 1;
+ lastwasinteger = 0;
+ }
+ else if (ch=='*') {
+ lastwasasterisk = 1;
+ lastwasinteger = 0;
+ }
+ else if (ch=='_') {
+ lastwasunderscore = 1;
+ lastwasinteger = 0;
+ }
+ else if (ch==";") {
+ section++; // start next section
+ thisformat.sectioninfo[section] = {}; // create a new section
+ sectioninfo = thisformat.sectioninfo[section]; // get reference to info for current section
+ sectioninfo.sectionstart = 1 + thisformat.operators.length; // remember where it starts
+ sectioninfo.integerdigits = 0; // number of integer-part placeholders
+ sectioninfo.fractiondigits = 0; // fraction placeholders
+ sectioninfo.commas = 0; // commas encountered, to handle scaling
+ sectioninfo.percent = 0; // times to scale by 100
+ integerpart = 1; // reset for new section
+ lastwasinteger = 0;
+ thisformat.operators.push(scfn.commands.section);
+ thisformat.operands.push(ch);
+ }
+ else if (ch.toLowerCase()=="g") {
+ ingeneral = 1;
+ lastwasinteger = 0;
+ }
+ else if (ch.toLowerCase()=="a") {
+ ampmstr = ch;
+ lastwasinteger = 0;
+ }
+ else if ("dmyhHs".indexOf(ch)>=0) {
+ indate = ch;
+ }
+ else {
+ lastwasinteger = 0;
+ thisformat.operators.push(scfn.commands.copy);
+ thisformat.operands.push(ch);
+ }
+ }
+
+ if (indate) { // last char was part of unsaved date placeholder
+ thisformat.operators.push(scfn.commands.date);
+ thisformat.operands.push(indate);
+ sectioninfo.hasdate = 1;
+ }
+
+ return;
+
+ }
+
+
+/* *******************
+
+ bracketdata = SocialCalc.FormatNumber.parse_format_bracket(bracketstr)
+
+ Takes a bracket contents (e.g., "RED", ">10") and returns an operator and operand
+
+ bracketdata->{}
+ .operator
+ .operand
+
+************************* */
+
+SocialCalc.FormatNumber.parse_format_bracket = function(bracketstr) {
+
+ var scfn = SocialCalc.FormatNumber;
+ var scc = SocialCalc.Constants;
+
+ var bracketdata={};
+ var parts;
+
+ if (bracketstr.charAt(0)=='$') { // currency
+ bracketdata.operator = scfn.commands.currency;
+ parts=bracketstr.match(/^\$(.+?)(\-.+?){0,1}$/);
+ if (parts) {
+ bracketdata.operand = parts[1] || scc.FormatNumber_defaultCurrency || '$';
+ }
+ else {
+ bracketdata.operand = bracketstr.substring(1) || scc.FormatNumber_defaultCurrency || '$';
+ }
+ }
+ else if (bracketstr=='?$') {
+ bracketdata.operator = scfn.commands.currency;
+ bracketdata.operand = '[?$]';
+ }
+ else if (scfn.allowedcolors[bracketstr.toUpperCase()]) {
+ bracketdata.operator = scfn.commands.color;
+ bracketdata.operand = scfn.allowedcolors[bracketstr.toUpperCase()];
+ }
+ else if (parts=bracketstr.match(/^style=([^"]*)$/)) { // [style=...]
+ bracketdata.operator = scfn.commands.style;
+ bracketdata.operand = parts[1];
+ }
+ else if (bracketstr==",") {
+ bracketdata.operator = scfn.commands.separator;
+ bracketdata.operand = bracketstr;
+ }
+ else if (scfn.alloweddates[bracketstr.toUpperCase()]) {
+ bracketdata.operator = scfn.commands.date;
+ bracketdata.operand = scfn.alloweddates[bracketstr.toUpperCase()];
+ }
+ else if (parts=bracketstr.match(/^[<>=]/)) { // comparison operator
+ parts=bracketstr.match(/^([<>=]+)(.+)$/); // split operator and value
+ bracketdata.operator = scfn.commands.comparison;
+ bracketdata.operand = parts[1]+":"+parts[2];
+ }
+ else { // unknown bracket
+ bracketdata.operator = scfn.commands.copy;
+ bracketdata.operand = "["+bracketstr+"]";
+ }
+
+ return bracketdata;
+
+ }
+
+/* *******************
+
+ juliandate = SocialCalc.FormatNumber.convert_date_gregorian_to_julian(year, month, day)
+
+ From: http://aa.usno.navy.mil/faq/docs/JD_Formula.html
+ Uses: Fliegel, H. F. and van Flandern, T. C. (1968). Communications of the ACM, Vol. 11, No. 10 (October, 1968).
+ Translated from the FORTRAN
+
+ I= YEAR
+ J= MONTH
+ K= DAY
+C
+ JD= K-32075+1461*(I+4800+(J-14)/12)/4+367*(J-2-(J-14)/12*12)
+ 2 /12-3*((I+4900+(J-14)/12)/100)/4
+
+************************* */
+
+SocialCalc.FormatNumber.convert_date_gregorian_to_julian = function(year, month, day) {
+
+ var juliandate;
+
+ juliandate = day-32075+SocialCalc.intFunc(1461*(year+4800+SocialCalc.intFunc((month-14)/12))/4);
+ juliandate += SocialCalc.intFunc(367*(month-2-SocialCalc.intFunc((month-14)/12)*12)/12);
+ juliandate = juliandate - SocialCalc.intFunc(3*SocialCalc.intFunc((year+4900+SocialCalc.intFunc((month-14)/12))/100)/4);
+
+ return juliandate;
+
+ }
+
+
+/* *******************
+
+ ymd = SocialCalc.FormatNumber.convert_date_julian_to_gregorian(juliandate)
+
+ ymd->{}
+ .year
+ .month
+ .day
+
+ From: http://aa.usno.navy.mil/faq/docs/JD_Formula.html
+ Uses: Fliegel, H. F. and van Flandern, T. C. (1968). Communications of the ACM, Vol. 11, No. 10 (October, 1968).
+ Translated from the FORTRAN
+
+************************* */
+
+SocialCalc.FormatNumber.convert_date_julian_to_gregorian = function(juliandate) {
+
+ var L, N, I, J, K;
+
+ L = juliandate+68569;
+ N = Math.floor(4*L/146097);
+ L = L-Math.floor((146097*N+3)/4);
+ I = Math.floor(4000*(L+1)/1461001);
+ L = L-Math.floor(1461*I/4)+31;
+ J = Math.floor(80*L/2447);
+ K = L-Math.floor(2447*J/80);
+ L = Math.floor(J/11);
+ J = J+2-12*L;
+ I = 100*(N-49)+I+L;
+
+ return {year:I, month:J, day:K};
+
+ }
+
+SocialCalc.intFunc = function(n) {
+ if (n < 0) {
+ return -Math.floor(-n);
+ }
+ else {
+ return Math.floor(n);
+ }
+ }
+
diff --git a/web/formula1.js b/web/formula1.js
new file mode 100644
index 0000000..99534e5
--- /dev/null
+++ b/web/formula1.js
@@ -0,0 +1,4754 @@
+//
+/*
+// SocialCalc Spreadsheet Formula Library
+//
+// Part of the SocialCalc package
+//
+// (c) Copyright 2008 Socialtext, Inc.
+// All Rights Reserved.
+//
+// The contents of this file are subject to the Artistic License 2.0; you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at http://socialcalc.org/licenses/al-20/.
+//
+// Some of the other files in the SocialCalc package are licensed under
+// different licenses. Please note the licenses of the modules you use.
+//
+// Code History:
+//
+// Initially coded by Dan Bricklin of Software Garden, Inc., for Socialtext, Inc.
+// Based in part on the SocialCalc 1.1.0 code written in Perl.
+// The SocialCalc 1.1.0 code was:
+// Portions (c) Copyright 2005, 2006, 2007 Software Garden, Inc.
+// All Rights Reserved.
+// Portions (c) Copyright 2007 Socialtext, Inc.
+// All Rights Reserved.
+// The Perl SocialCalc started as modifications to the wikiCalc(R) program, version 1.0.
+// wikiCalc 1.0 was written by Software Garden, Inc.
+// Unless otherwise specified, referring to "SocialCalc" in comments refers to this
+// JavaScript version of the code, not the SocialCalc Perl code.
+//
+*/
+
+ var SocialCalc;
+ if (!SocialCalc) SocialCalc = {}; // May be used with other SocialCalc libraries or standalone
+ // In any case, requires SocialCalc.Constants.
+
+SocialCalc.Formula = {};
+
+//
+// Formula constants for parsing:
+//
+
+ SocialCalc.Formula.ParseState = {num: 1, alpha: 2, coord: 3, string: 4, stringquote: 5, numexp1: 6, numexp2: 7, alphanumeric: 8, specialvalue:9};
+
+ SocialCalc.Formula.TokenType = {num: 1, coord: 2, op: 3, name: 4, error: 5, string: 6, space: 7};
+
+ SocialCalc.Formula.CharClass = {num: 1, numstart: 2, op: 3, eof: 4, alpha: 5, incoord: 6, error: 7, quote: 8, space: 9, specialstart: 10};
+
+ SocialCalc.Formula.CharClassTable = {
+ " ": 9, "!": 3, '"': 8, "#": 10, "$":6, "%":3, "&":3, "(": 3, ")": 3, "*": 3, "+": 3, ",": 3, "-": 3, ".": 2, "/": 3,
+ "0": 1, "1": 1, "2": 1, "3": 1, "4": 1, "5": 1, "6": 1, "7": 1, "8": 1, "9": 1,
+ ":": 3, "<": 3, "=": 3, ">": 3,
+ "A": 5, "B": 5, "C": 5, "D": 5, "E": 5, "F": 5, "G": 5, "H": 5, "I": 5, "J": 5, "K": 5, "L": 5, "M": 5, "N": 5,
+ "O": 5, "P": 5, "Q": 5, "R": 5, "S": 5, "T": 5, "U": 5, "V": 5, "W": 5, "X": 5, "Y": 5, "Z": 5,
+ "^": 3, "_": 5,
+ "a": 5, "b": 5, "c": 5, "d": 5, "e": 5, "f": 5, "g": 5, "h": 5, "i": 5, "j": 5, "k": 5, "l": 5, "m": 5, "n": 5,
+ "o": 5, "p": 5, "q": 5, "r": 5, "s": 5, "t": 5, "u": 5, "v": 5, "w": 5, "x": 5, "y": 5, "z": 5
+ };
+
+ SocialCalc.Formula.UpperCaseTable = {
+ "a": "A", "b": "B", "c": "C", "d": "D", "e": "E", "f": "F", "g": "G", "h": "H", "i": "I", "j": "J", "k": "K", "l": "L", "m": "M",
+ "n": "N", "o": "O", "p": "P", "q": "Q", "r": "R", "s": "S", "t": "T", "u": "U", "v": "V", "w": "W", "x": "X", "y": "Y", "z": "Z"
+ }
+
+ SocialCalc.Formula.SpecialConstants = { // names that turn into constants for name lookup
+ "#NULL!": "0,e#NULL!", "#NUM!": "0,e#NUM!", "#DIV/0!": "0,e#DIV/0!", "#VALUE!": "0,e#VALUE!",
+ "#REF!": "0,e#REF!", "#NAME?": "0,e#NAME?"};
+
+
+ // Operator Precedence table
+ //
+ // 1- !, 2- : ,, 3- M P, 4- %, 5- ^, 6- * /, 7- + -, 8- &, 9- < > = G(>=) L(<=) N(<>),
+ // Negative value means Right Associative
+
+ SocialCalc.Formula.TokenPrecedence = {
+ "!": 1,
+ ":": 2, ",": 2,
+ "M": -3, "P": -3,
+ "%": 4,
+ "^": 5,
+ "*": 6, "/": 6,
+ "+": 7, "-": 7,
+ "&": 8,
+ "<": 9, ">": 9, "G": 9, "L": 9, "N": 9
+ };
+
+ // Convert one-char token text to input text:
+
+ SocialCalc.Formula.TokenOpExpansion = {'G': '>=', 'L': '<=', 'M': '-', 'N': '<>', 'P': '+'};
+
+ //
+ // Information about the resulting value types when doing operations on values (used by LookupResultType)
+ //
+ // Each object entry is an object with specific types with result type info as follows:
+ //
+ // 'type1a': '|type2a:resulta|type2b:resultb|...
+ // Type of t* or n* matches any of those types not listed
+ // Results may be a type or the numbers 1 or 2 specifying to return type1 or type2
+
+
+ SocialCalc.Formula.TypeLookupTable = {
+ unaryminus: { 'n*': '|n*:1|', 'e*': '|e*:1|', 't*': '|t*:e#VALUE!|', 'b': '|b:n|'},
+ unaryplus: { 'n*': '|n*:1|', 'e*': '|e*:1|', 't*': '|t*:e#VALUE!|', 'b': '|b:n|'},
+ unarypercent: { 'n*': '|n:n%|n*:n|', 'e*': '|e*:1|', 't*': '|t*:e#VALUE!|', 'b': '|b:n|'},
+ plus: {
+ 'n%': '|n%:n%|nd:n|nt:n|ndt:n|n$:n|n:n|n*:n|b:n|e*:2|t*:e#VALUE!|',
+ 'nd': '|n%:n|nd:nd|nt:ndt|ndt:ndt|n$:n|n:nd|n*:n|b:n|e*:2|t*:e#VALUE!|',
+ 'nt': '|n%:n|nd:ndt|nt:nt|ndt:ndt|n$:n|n:nt|n*:n|b:n|e*:2|t*:e#VALUE!|',
+ 'ndt': '|n%:n|nd:ndt|nt:ndt|ndt:ndt|n$:n|n:ndt|n*:n|b:n|e*:2|t*:e#VALUE!|',
+ 'n$': '|n%:n|nd:n|nt:n|ndt:n|n$:n$|n:n$|n*:n|b:n|e*:2|t*:e#VALUE!|',
+ 'nl': '|n%:n|nd:n|nt:n|ndt:n|n$:n|n:n|n*:n|b:n|e*:2|t*:e#VALUE!|',
+ 'n': '|n%:n|nd:nd|nt:nt|ndt:ndt|n$:n$|n:n|n*:n|b:n|e*:2|t*:e#VALUE!|',
+ 'b': '|n%:n%|nd:nd|nt:nt|ndt:ndt|n$:n$|n:n|n*:n|b:n|e*:2|t*:e#VALUE!|',
+ 't*': '|n*:e#VALUE!|t*:e#VALUE!|b:e#VALUE!|e*:2|',
+ 'e*': '|e*:1|n*:1|t*:1|b:1|'
+ },
+ concat: {
+ 't': '|t:t|th:th|tw:tw|tl:t|t*:2|e*:2|',
+ 'th': '|t:th|th:th|tw:t|tl:th|t*:t|e*:2|',
+ 'tw': '|t:tw|th:t|tw:tw|tl:tw|t*:t|e*:2|',
+ 'tl': '|t:tl|th:th|tw:tw|tl:tl|t*:t|e*:2|',
+ 'e*': '|e*:1|n*:1|t*:1|'
+ },
+ oneargnumeric: { 'n*': '|n*:n|', 'e*': '|e*:1|', 't*': '|t*:e#VALUE!|', 'b': '|b:n|'},
+ twoargnumeric: { 'n*': '|n*:n|t*:e#VALUE!|e*:2|', 'e*': '|e*:1|n*:1|t*:1|', 't*': '|t*:e#VALUE!|n*:e#VALUE!|e*:2|'},
+ propagateerror: { 'n*': '|n*:2|e*:2|', 'e*': '|e*:2|', 't*': '|t*:2|e*:2|', 'b': '|b:2|e*:2|'}
+ };
+
+/* *******************
+
+ parseinfo = SocialCalc.Formula.ParseFormulaIntoTokens(line)
+
+ Parses a text string as if it was a spreadsheet formula
+
+ This uses a simple state machine run on each character in turn.
+ States remember whether a number is being gathered, etc.
+ The result is parseinfo which is an array with one entry for each token:
+ parseinfo[i] = {
+ text: "the characters making up the parsed token",
+ type: the type of the token (a number),
+ opcode: a single character version of an operator suitable for use in the
+ precedence table and distinguishing between unary and binary + and -.
+
+************************* */
+
+SocialCalc.Formula.ParseFormulaIntoTokens = function(line) {
+
+ var i, ch, chclass, haddecimal, last_token, last_token_type, last_token_text, t;
+
+ var scf = SocialCalc.Formula;
+ var scc = SocialCalc.Constants;
+ var parsestate = scf.ParseState;
+ var tokentype = scf.TokenType;
+ var charclass = scf.CharClass;
+ var charclasstable = scf.CharClassTable;
+ var uppercasetable = scf.UpperCaseTable; // much faster than toUpperCase function
+ var pushtoken = scf.ParsePushToken;
+ var coordregex = /^\$?[A-Z]{1,2}\$?[1-9]\d*$/i;
+
+ var parseinfo = [];
+ var str = "";
+ var state = 0;
+ var haddecimal = false;
+
+ for (i=0; i<=line.length; i++) {
+ if (i<line.length) {
+ ch = line.charAt(i);
+ cclass = charclasstable[ch];
+ }
+ else {
+ ch = "";
+ cclass = charclass.eof;
+ }
+
+ if (state == parsestate.num) {
+ if (cclass == charclass.num) {
+ str += ch;
+ }
+ else if (cclass == charclass.numstart && !haddecimal) {
+ haddecimal = true;
+ str += ch;
+ }
+ else if (ch == "E" || ch == "e") {
+ str += ch;
+ haddecimal = false;
+ state = parsestate.numexp1;
+ }
+ else { // end of number - save it
+ pushtoken(parseinfo, str, tokentype.num, 0);
+ haddecimal = false;
+ state = 0;
+ }
+ }
+
+ if (state == parsestate.numexp1) {
+ if (cclass == parsestate.num) {
+ state = parsestate.numexp2;
+ }
+ else if ((ch == '+' || ch == '-') && (uppercasetable[str.charAt(str.length-1)] == 'E')) {
+ str += ch;
+ }
+ else if (ch == 'E' || ch == 'e') {
+ ;
+ }
+ else {
+ pushtoken(parseinfo, scc.s_parseerrexponent, tokentype.error, 0);
+ state = 0;
+ }
+ }
+
+ if (state == parsestate.numexp2) {
+ if (cclass == charclass.num) {
+ str += ch;
+ }
+ else { // end of number - save it
+ pushtoken(parseinfo, str, tokentype.num, 0);
+ state = 0;
+ }
+ }
+
+ if (state == parsestate.alpha) {
+ if (cclass == charclass.num) {
+ state = parsestate.coord;
+ }
+ else if (cclass == charclass.alpha || ch == ".") { // alpha may be letters, numbers, "_", or "."
+ str += ch;
+ }
+ else if (cclass == charclass.incoord) {
+ state = parsestate.coord;
+ }
+ else if (cclass == charclass.op || cclass == charclass.numstart
+ || cclass == charclass.space || cclass == charclass.eof) {
+ pushtoken(parseinfo, str.toUpperCase(), tokentype.name, 0);
+ state = 0;
+ }
+ else {
+ pushtoken(parseinfo, scc.s_parseerrchar, tokentype.error, 0);
+ state = 0;
+ }
+ }
+
+ if (state == parsestate.coord) {
+ if (cclass == charclass.num) {
+ str += ch;
+ }
+ else if (cclass == charclass.incoord) {
+ str += ch;
+ }
+ else if (cclass == charclass.alpha) {
+ state = parsestate.alphanumeric;
+ }
+ else if (cclass == charclass.op || cclass == charclass.numstart ||
+ cclass == charclass.eof || cclass == charclass.space) {
+ if (coordregex.test(str)) {
+ t = tokentype.coord;
+ }
+ else {
+ t = tokentype.name;
+ }
+ pushtoken(parseinfo, str.toUpperCase(), t, 0);
+ state = 0;
+ }
+ else {
+ pushtoken(parseinfo, scc.s_parseerrchar, tokentype.error, 0);
+ state = 0;
+ }
+ }
+
+
+ if (state == parsestate.alphanumeric) {
+ if (cclass == charclass.num || cclass == charclass.alpha) {
+ str += ch;
+ }
+ else if (cclass == charclass.op || cclass == charclass.numstart
+ || cclass == charclass.space || cclass == charclass.eof) {
+ pushtoken(parseinfo, str.toUpperCase(), tokentype.name, 0);
+ state = 0;
+ }
+ else {
+ pushtoken(parseinfo, scc.s_parseerrchar, tokentype.error, 0);
+ state = 0;
+ }
+ }
+
+ if (state == parsestate.string) {
+ if (cclass == charclass.quote) {
+ state = parsestate.stringquote; // got quote in string: is it doubled (quote in string) or by itself (end of string)?
+ }
+ else if (cclass == charclass.eof) {
+ pushtoken(parseinfo, scc.s_parseerrstring, tokentype.error, 0);
+ state = 0;
+ }
+ else {
+ str += ch;
+ }
+ }
+ else if (state == parsestate.stringquote) { // note else if here
+ if (cclass == charclass.quote) {
+ str +='"';
+ state = parsestate.string; // double quote: add one then continue getting string
+ }
+ else { // something else -- end of string
+ pushtoken(parseinfo, str, tokentype.string, 0);
+ state = 0; // drop through to process
+ }
+ }
+
+ else if (state == parsestate.specialvalue) { // special values like #REF!
+ if (str.charAt(str.length-1) == "!") { // done - save value as a name
+ pushtoken(parseinfo, str, tokentype.name, 0);
+ state = 0; // drop through to process
+ }
+ else if (cclass == charclass.eof) {
+ pushtoken(parseinfo, scc.s_parseerrspecialvalue, tokentype.error, 0);
+ state = 0;
+ }
+ else {
+ str += ch;
+ }
+ }
+
+ if (state == 0) {
+ if (cclass == charclass.num) {
+ str = ch;
+ state = parsestate.num;
+ }
+ else if (cclass == charclass.numstart) {
+ str = ch;
+ haddecimal = true;
+ state = parsestate.num;
+ }
+ else if (cclass == charclass.alpha || cclass == charclass.incoord) {
+ str = ch;
+ state = parsestate.alpha;
+ }
+ else if (cclass == charclass.specialstart) {
+ str = ch;
+ state = parsestate.specialvalue;
+ }
+ else if (cclass == charclass.op) {
+ str = ch;
+ if (parseinfo.length>0) {
+ last_token = parseinfo[parseinfo.length-1];
+ last_token_type = last_token.type;
+ last_token_text = last_token.text;
+ if (last_token_type == charclass.op) {
+ if (last_token_text == '<' || last_token_text == ">") {
+ str = last_token_text + str;
+ parseinfo.pop();
+ if (parseinfo.length>0) {
+ last_token = parseinfo[parseinfo.length-1];
+ last_token_type = last_token.type;
+ last_token_text = last_token.text;
+ }
+ else {
+ last_token_type = charclass.eof;
+ last_token_text = "EOF";
+ }
+ }
+ }
+ }
+ else {
+ last_token_type = charclass.eof;
+ last_token_text = "EOF";
+ }
+ t = tokentype.op;
+ if ((parseinfo.length == 0)
+ || (last_token_type == charclass.op && last_token_text != ')' && last_token_text != '%')) { // Unary operator
+ if (str == '-') { // M is unary minus
+ str = "M";
+ ch = "M";
+ }
+ else if (str == '+') { // P is unary plus
+ str = "P";
+ ch = "P";
+ }
+ else if (str == ')' && last_token_text == '(') { // null arg list OK
+ ;
+ }
+ else if (str != '(') { // binary-op open-paren OK, others no
+ t = tokentype.error;
+ str = scc.s_parseerrtwoops;
+ }
+ }
+ else if (str.length > 1) {
+ if (str == '>=') { // G is >=
+ str = "G";
+ ch = "G";
+ }
+ else if (str == '<=') { // L is <=
+ str = "L";
+ ch = "L";
+ }
+ else if (str == '<>') { // N is <>
+ str = "N";
+ ch = "N";
+ }
+ else {
+ t = tokentype.error;
+ str = scc.s_parseerrtwoops;
+ }
+ }
+ pushtoken(parseinfo, str, t, ch);
+ state = 0;
+ }
+ else if (cclass == charclass.quote) { // starting a string
+ str = "";
+ state = parsestate.string;
+ }
+ else if (cclass == charclass.space) { // store so can reconstruct spacing
+ pushtoken(parseinfo, " ", tokentype.space, 0);
+ }
+ else if (cclass == charclass.eof) { // ignore -- needed to have extra loop to close out other things
+ }
+ else { // unknown class - such as unknown char
+ pushtoken(parseinfo, scc.s_parseerrchar, tokentype.error, 0);
+ }
+ }
+ }
+
+ return parseinfo;
+
+ }
+
+SocialCalc.Formula.ParsePushToken = function(parseinfo, ttext, ttype, topcode) {
+
+ parseinfo.push({text: ttext, type: ttype, opcode: topcode});
+
+ }
+
+/* *******************
+
+ result = SocialCalc.Formula.evaluate_parsed_formula(parseinfo, sheet, allowrangereturn)
+
+ Does the calculation expressed in a parsed formula, returning a value, its type, and error info
+ returns: {value: value, type: valuetype, error: errortext}.
+
+ If allowrangereturn is present and true, can return a range (e.g., "A1:A10" - translated from "A1|A10|")
+
+************************* */
+
+SocialCalc.Formula.evaluate_parsed_formula = function(parseinfo, sheet, allowrangereturn) {
+
+ var result;
+
+ var scf = SocialCalc.Formula;
+ var tokentype = scf.TokenType;
+
+ var revpolish;
+ var parsestack = [];
+
+ var errortext = "";
+
+ revpolish = scf.ConvertInfixToPolish(parseinfo); // result is either an array or a string with error text
+
+ result = scf.EvaluatePolish(parseinfo, revpolish, sheet, allowrangereturn);
+
+ return result;
+
+}
+
+//
+// revpolish = SocialCalc.Formula.ConvertInfixToPolish(parseinfo)
+//
+// Convert infix to reverse polish notation
+//
+// Returns revpolish array with a sequence of references to tokens by number if successful.
+// Errors return a string with the error.
+//
+// Based upon the algorithm shown in Wikipedia "Reverse Polish notation" article
+// and then enhanced for additional spreadsheet things
+//
+
+SocialCalc.Formula.ConvertInfixToPolish = function(parseinfo) {
+
+ var scf = SocialCalc.Formula;
+ var scc = SocialCalc.Constants;
+ var tokentype = scf.TokenType;
+ var token_precedence = scf.TokenPrecedence;
+
+ var revpolish = [];
+ var parsestack = [];
+
+ var errortext = "";
+
+ var function_start = -1;
+
+ var i, pii, ttype, ttext, tprecedence, tstackprecedence;
+
+ for (i=0; i<parseinfo.length; i++) {
+ pii = parseinfo[i];
+ ttype = pii.type;
+ ttext = pii.text;
+ if (ttype == tokentype.num || ttype == tokentype.coord || ttype == tokentype.string) {
+ revpolish.push(i);
+ }
+ else if (ttype == tokentype.name) {
+ parsestack.push(i);
+ revpolish.push(function_start);
+ }
+ else if (ttype == tokentype.space) { // ignore
+ continue;
+ }
+ else if (ttext == ',') {
+ while (parsestack.length && parseinfo[parsestack[parsestack.length-1]].text != "(") {
+ revpolish.push(parsestack.pop());
+ }
+ if (parsestack.length == 0) { // no ( -- error
+ errortext = scc.s_parseerrmissingopenparen;
+ break;
+ }
+ }
+ else if (ttext == '(') {
+ parsestack.push(i);
+ }
+ else if (ttext == ')') {
+ while (parsestack.length && parseinfo[parsestack[parsestack.length-1]].text != "(") {
+ revpolish.push(parsestack.pop());
+ }
+ if (parsestack.length == 0) { // no ( -- error
+ errortext = scc.s_parseerrcloseparennoopen;
+ break;
+ }
+ parsestack.pop();
+ if (parsestack.length && parseinfo[parsestack[parsestack.length-1]].type == tokentype.name) {
+ revpolish.push(parsestack.pop());
+ }
+ }
+ else if (ttype == tokentype.op) {
+ if (parsestack.length && parseinfo[parsestack[parsestack.length-1]].type == tokentype.name) {
+ revpolish.push(parsestack.pop());
+ }
+ while (parsestack.length && parseinfo[parsestack[parsestack.length-1]].type == tokentype.op
+ && parseinfo[parsestack[parsestack.length-1]].text != '(') {
+ tprecedence = token_precedence[pii.opcode];
+ tstackprecedence = token_precedence[parseinfo[parsestack[parsestack.length-1]].opcode];
+ if (tprecedence >= 0 && tprecedence < tstackprecedence) {
+ break;
+ }
+ else if (tprecedence < 0) {
+ tprecedence = -tprecedence;
+ if (tstackprecedence < 0) tstackprecedence = -tstackprecedence;
+ if (tprecedence <= tstackprecedence) {
+ break;
+ }
+ }
+ revpolish.push(parsestack.pop());
+ }
+ parsestack.push(i);
+ }
+ else if (ttype == tokentype.error) {
+ errortext = ttext;
+ break;
+ }
+ else {
+ errortext = "Internal error while processing parsed formula. ";
+ break;
+ }
+ }
+ while (parsestack.length>0) {
+ if (parseinfo[parsestack[parsestack.length-1]].text == '(') {
+ errortext = scc.s_parseerrmissingcloseparen;
+ break;
+ }
+ revpolish.push(parsestack.pop());
+ }
+
+ if (errortext) {
+ return errortext;
+ }
+
+ return revpolish;
+
+ }
+
+
+//
+// result = SocialCalc.Formula.EvaluatePolish(parseinfo, revpolish, sheet, allowrangereturn)
+//
+// Execute reverse polish representation of formula
+//
+// Operand values are objects in the operand array with a "type" and an optional "value".
+// Type can have these values (many are type and sub-type as two or more letters):
+// "tw", "th", "t", "n", "nt", "coord", "range", "start", "eErrorType", "b" (blank)
+// The value of a coord is in the form A57 or A57!sheetname
+// The value of a range is coord|coord|number where number starts at 0 and is
+// the offset of the next item to fetch if you are going through the range one by one
+// The number starts as a null string ("A1|B3|")
+//
+
+SocialCalc.Formula.EvaluatePolish = function(parseinfo, revpolish, sheet, allowrangereturn) {
+
+ var scf = SocialCalc.Formula;
+ var scc = SocialCalc.Constants;
+ var tokentype = scf.TokenType;
+ var lookup_result_type = scf.LookupResultType;
+ var typelookup = scf.TypeLookupTable;
+ var operand_as_number = scf.OperandAsNumber;
+ var operand_as_text = scf.OperandAsText;
+ var operand_value_and_type = scf.OperandValueAndType;
+ var operands_as_coord_on_sheet = scf.OperandsAsCoordOnSheet;
+ var format_number_for_display = SocialCalc.format_number_for_display || function(v, t, f) {return v+"";};
+
+ var errortext = "";
+ var function_start = -1;
+ var missingOperandError = {value: "", type: "e#VALUE!", error: scc.s_parseerrmissingoperand};
+
+ var operand = [];
+ var PushOperand = function(t, v) {operand.push({type: t, value: v});};
+
+ var i, rii, prii, ttype, ttext, value1, value2, tostype, tostype2, resulttype, valuetype, cond, vmatch, smatch;
+
+ if (!parseinfo.length || (! (revpolish instanceof Array))) {
+ return ({value: "", type: "e#VALUE!", error: (typeof revpolish == "string" ? revpolish : "")});
+ }
+
+ for (i=0; i<revpolish.length; i++) {
+ rii = revpolish[i];
+ if (rii == function_start) { // Remember the start of a function argument list
+ PushOperand("start", 0);
+ continue;
+ }
+
+ prii = parseinfo[rii];
+ ttype = prii.type;
+ ttext = prii.text;
+
+ if (ttype == tokentype.num) {
+ PushOperand("n", ttext-0);
+ }
+
+ else if (ttype == tokentype.coord) {
+ PushOperand("coord", ttext);
+ }
+
+ else if (ttype == tokentype.string) {
+ PushOperand("t", ttext);
+ }
+
+ else if (ttype == tokentype.op) {
+ if (operand.length <= 0) { // Nothing on the stack...
+ return missingOperandError;
+ break; // done
+ }
+
+ // Unary minus
+
+ if (ttext == 'M') {
+ value1 = operand_as_number(sheet, operand);
+ resulttype = lookup_result_type(value1.type, value1.type, typelookup.unaryminus);
+ PushOperand(resulttype, -value1.value);
+ }
+
+ // Unary plus
+
+ else if (ttext == 'P') {
+ value1 = operand_as_number(sheet, operand);
+ resulttype = lookup_result_type(value1.type, value1.type, typelookup.unaryplus);
+ PushOperand(resulttype, value1.value);
+ }
+
+ // Unary % - percent, left associative
+
+ else if (ttext == '%') {
+ value1 = operand_as_number(sheet, operand);
+ resulttype = lookup_result_type(value1.type, value1.type, typelookup.unarypercent);
+ PushOperand(resulttype, 0.01*value1.value);
+ }
+
+ // & - string concatenate
+
+ else if (ttext == '&') {
+ if (operand.length <= 1) { // Need at least two things on the stack...
+ return missingOperandError;
+ }
+ value2 = operand_as_text(sheet, operand);
+ value1 = operand_as_text(sheet, operand);
+ resulttype = lookup_result_type(value1.type, value1.type, typelookup.concat);
+ PushOperand(resulttype, value1.value + value2.value);
+ }
+
+ // : - Range constructor
+
+ else if (ttext == ':') {
+ if (operand.length <= 1) { // Need at least two things on the stack...
+ return missingOperandError;
+ }
+ value1 = scf.OperandsAsRangeOnSheet(sheet, operand); // get coords even if use name on other sheet
+ if (value1.error) { // not available
+ errortext = errortext || value1.error;
+ }
+ PushOperand(value1.type, value1.value); // push sheetname with range on that sheet
+ }
+
+ // ! - sheetname!coord
+
+ else if (ttext == '!') {
+ if (operand.length <= 1) { // Need at least two things on the stack...
+ return missingOperandError;
+ }
+ value1 = operands_as_coord_on_sheet(sheet, operand); // get coord even if name on other sheet
+ if (value1.error) { // not available
+ errortext = errortext || value1.error;
+ }
+ PushOperand(value1.type, value1.value); // push sheetname with coord or range on that sheet
+ }
+
+ // Comparison operators: < L = G > N (< <= = >= > <>)
+
+ else if (ttext == "<" || ttext == "L" || ttext == "=" || ttext == "G" || ttext == ">" || ttext == "N") {
+ if (operand.length <= 1) { // Need at least two things on the stack...
+ errortext = scc.s_parseerrmissingoperand; // remember error
+ break;
+ }
+ value2 = operand_value_and_type(sheet, operand);
+ value1 = operand_value_and_type(sheet, operand);
+ if (value1.type.charAt(0) == "n" && value2.type.charAt(0) == "n") { // compare two numbers
+ cond = 0;
+ if (ttext == "<") { cond = value1.value < value2.value ? 1 : 0; }
+ else if (ttext == "L") { cond = value1.value <= value2.value ? 1 : 0; }
+ else if (ttext == "=") { cond = value1.value == value2.value ? 1 : 0; }
+ else if (ttext == "G") { cond = value1.value >= value2.value ? 1 : 0; }
+ else if (ttext == ">") { cond = value1.value > value2.value ? 1 : 0; }
+ else if (ttext == "N") { cond = value1.value != value2.value ? 1 : 0; }
+ PushOperand("nl", cond);
+ }
+ else if (value1.type.charAt(0) == "e") { // error on left
+ PushOperand(value1.type, 0);
+ }
+ else if (value2.type.charAt(0) == "e") { // error on right
+ PushOperand(value2.type, 0);
+ }
+ else { // text maybe mixed with numbers or blank
+ tostype = value1.type.charAt(0);
+ tostype2 = value2.type.charAt(0);
+ if (tostype == "n") {
+ value1.value = format_number_for_display(value1.value, "n", "");
+ }
+ else if (tostype == "b") {
+ value1.value = "";
+ }
+ if (tostype2 == "n") {
+ value2.value = format_number_for_display(value2.value, "n", "");
+ }
+ else if (tostype2 == "b") {
+ value2.value = "";
+ }
+ cond = 0;
+ value1.value = value1.value.toLowerCase(); // ignore case
+ value2.value = value2.value.toLowerCase();
+ if (ttext == "<") { cond = value1.value < value2.value ? 1 : 0; }
+ else if (ttext == "L") { cond = value1.value <= value2.value ? 1 : 0; }
+ else if (ttext == "=") { cond = value1.value == value2.value ? 1 : 0; }
+ else if (ttext == "G") { cond = value1.value >= value2.value ? 1 : 0; }
+ else if (ttext == ">") { cond = value1.value > value2.value ? 1 : 0; }
+ else if (ttext == "N") { cond = value1.value != value2.value ? 1 : 0; }
+ PushOperand("nl", cond);
+ }
+ }
+
+ // Normal infix arithmethic operators: +, -. *, /, ^
+
+ else { // what's left are the normal infix arithmetic operators
+ if (operand.length <= 1) { // Need at least two things on the stack...
+ errortext = scc.s_parseerrmissingoperand; // remember error
+ break;
+ }
+ value2 = operand_as_number(sheet, operand);
+ value1 = operand_as_number(sheet, operand);
+ if (ttext == '+') {
+ resulttype = lookup_result_type(value1.type, value2.type, typelookup.plus);
+ PushOperand(resulttype, value1.value + value2.value);
+ }
+ else if (ttext == '-') {
+ resulttype = lookup_result_type(value1.type, value2.type, typelookup.plus);
+ PushOperand(resulttype, value1.value - value2.value);
+ }
+ else if (ttext == '*') {
+ resulttype = lookup_result_type(value1.type, value2.type, typelookup.plus);
+ PushOperand(resulttype, value1.value * value2.value);
+ }
+ else if (ttext == '/') {
+ if (value2.value != 0) {
+ PushOperand("n", value1.value / value2.value); // gives plain numeric result type
+ }
+ else {
+ PushOperand("e#DIV/0!", 0);
+ }
+ }
+ else if (ttext == '^') {
+ value1.value = Math.pow(value1.value, value2.value);
+ value1.type = "n"; // gives plain numeric result type
+ if (isNaN(value1.value)) {
+ value1.value = 0;
+ value1.type = "e#NUM!";
+ }
+ PushOperand(value1.type, value1.value);
+ }
+ }
+ }
+
+ // function or name
+
+ else if (ttype == tokentype.name) {
+ errortext = scf.CalculateFunction(ttext, operand, sheet);
+ if (errortext) break;
+ }
+
+ else {
+ errortext = scc.s_InternalError+"Unknown token "+ttype+" ("+ttext+"). ";
+ break;
+ }
+ }
+
+ // look at final value and handle special cases
+
+ value = operand[0] ? operand[0].value : "";
+ tostype = operand[0] ? operand[0].type : "";
+
+ if (tostype == "name") { // name - expand it
+ value1 = SocialCalc.Formula.LookupName(sheet, value);
+ value = value1.value;
+ tostype = value1.type;
+ errortext = errortext || value1.error;
+ }
+
+ if (tostype == "coord") { // the value is a coord reference, get its value and type
+ value1 = operand_value_and_type(sheet, operand);
+ value = value1.value;
+ tostype = value1.type;
+ if (tostype == "b") {
+ tostype = "n";
+ value = 0;
+ }
+ }
+
+ if (operand.length > 1 && !errortext) { // something left - error
+ errortext += scc.s_parseerrerrorinformula;
+ }
+
+ // set return type
+
+ valuetype = tostype;
+
+ if (tostype.charAt(0) == "e") { // error value
+ errortext = errortext || tostype.substring(1) || scc.s_calcerrerrorvalueinformula;
+ }
+ else if (tostype == "range") {
+ vmatch = value.match(/^(.*)\|(.*)\|/);
+ smatch = vmatch[1].indexOf("!");
+ if (smatch>=0) { // swap sheetname
+ vmatch[1] = vmatch[1].substring(smatch+1) + "!" + vmatch[1].substring(0, smatch).toUpperCase();
+ }
+ else {
+ vmatch[1] = vmatch[1].toUpperCase();
+ }
+ value = vmatch[1] + ":" + vmatch[2].toUpperCase();
+ if (!allowrangereturn) {
+ errortext = scc.s_formularangeresult+" "+value;
+ }
+ }
+
+ if (errortext && valuetype.charAt(0) != "e") {
+ value = errortext;
+ valuetype = "e";
+ }
+
+ // look for overflow
+
+ if (valuetype.charAt(0) == "n" && (isNaN(value) || !isFinite(value))) {
+ value = 0;
+ valuetype = "e#NUM!";
+ errortext = isNaN(value) ? scc.s_calcerrnumericnan: scc.s_calcerrnumericoverflow;
+ }
+
+ return ({value: value, type: valuetype, error: errortext});
+
+ }
+
+
+/*
+#
+# resulttype = SocialCalc.Formula.LookupResultType(type1, type2, typelookup);
+#
+# typelookup has values of the following form:
+#
+# typelookup{"typespec1"} = "|typespec2A:resultA|typespec2B:resultB|..."
+#
+# First type1 is looked up. If no match, then the first letter (major type) of type1 plus "*" is looked up
+# resulttype is type1 if result is "1", type2 if result is "2", otherwise the value of result.
+#
+*/
+
+SocialCalc.Formula.LookupResultType = function(type1, type2, typelookup) {
+
+ var pos1, pos2, result;
+
+ var table1 = typelookup[type1];
+
+ if (!table1) {
+ table1 = typelookup[type1.charAt(0)+'*'];
+ if (!table1) {
+ return "e#VALUE! (internal error, missing LookupResultType "+type1.charAt(0)+"*)"; // missing from table -- please add it
+ }
+ }
+ pos1 = table1.indexOf("|"+type2+":");
+ if (pos1 >= 0) {
+ pos2 = table1.indexOf("|", pos1+1);
+ if (pos2<0) return "e#VALUE! (internal error, incorrect LookupResultType "+table1+")";
+ result = table1.substring(pos1+type2.length+2, pos2);
+ if (result == "1") return type1;
+ if (result == "2") return type2;
+ return result;
+ }
+ pos1 = table1.indexOf("|"+type2.charAt(0)+"*:");
+ if (pos1 >= 0) {
+ pos2 = table1.indexOf("|", pos1+1);
+ if (pos2<0) return "e#VALUE! (internal error, incorrect LookupResultType "+table1+")";
+ result = table1.substring(pos1+4, pos2);
+ if (result == "1") return type1;
+ if (result == "2") return type2;
+ return result;
+ }
+ return "e#VALUE!";
+
+ }
+
+/*
+#
+# operandinfo = SocialCalc.Formula.TopOfStackValueAndType(sheet, operand)
+#
+# Returns top of stack value and type and then pops the stack.
+# The result is {value: value, type: type, error: "only if bad error"}
+#
+*/
+
+SocialCalc.Formula.TopOfStackValueAndType = function(sheet, operand) {
+
+ var cellvtype, cell, pos, coordsheet;
+ var scf = SocialCalc.Formula;
+
+ var result = {type: "", value: ""};
+
+ var stacklen = operand.length;
+
+ if (!stacklen) { // make sure something is there
+ result.error = SocialCalc.Constants.s_InternalError+"no operand on stack";
+ return result;
+ }
+
+ result.value = operand[stacklen-1].value; // get top of stack
+ result.type = operand[stacklen-1].type;
+ operand.pop(); // we have data - pop stack
+
+ if (result.type == "name") {
+ result = scf.LookupName(sheet, result.value);
+ }
+
+ return result;
+
+ }
+
+
+/*
+#
+# operandinfo = OperandAsNumber(sheet, operand)
+#
+# Uses operand_value_and_type to get top of stack and pops it.
+# Returns numeric value and type.
+# Text values are treated as 0 if they can't be converted somehow.
+#
+*/
+
+SocialCalc.Formula.OperandAsNumber = function(sheet, operand) {
+
+ var t, valueinfo;
+ var operandinfo = SocialCalc.Formula.OperandValueAndType(sheet, operand);
+
+ t = operandinfo.type.charAt(0);
+
+ if (t == "n") {
+ operandinfo.value = operandinfo.value-0;
+ }
+ else if (t == "b") { // blank cell
+ operandinfo.type = "n";
+ operandinfo.value = 0;
+ }
+ else if (t == "e") { // error
+ operandinfo.value = 0;
+ }
+ else {
+ valueinfo = SocialCalc.DetermineValueType ? SocialCalc.DetermineValueType(operandinfo.value) :
+ {value: operandinfo.value-0, type: "n"}; // if without rest of SocialCalc
+ if (valueinfo.type.charAt(0) == "n") {
+ operandinfo.value = valueinfo.value-0;
+ operandinfo.type = valueinfo.type;
+ }
+ else {
+ operandinfo.value = 0;
+ operandinfo.type = valueinfo.type;
+ }
+ }
+
+ return operandinfo;
+
+ }
+
+/*
+#
+# operandinfo = OperandAsText(sheet, operand)
+#
+# Uses operand_value_and_type to get top of stack and pops it.
+# Returns text value, preserving sub-type.
+#
+*/
+
+SocialCalc.Formula.OperandAsText = function(sheet, operand) {
+
+ var t, valueinfo;
+ var operandinfo = SocialCalc.Formula.OperandValueAndType(sheet, operand);
+
+ t = operandinfo.type.charAt(0);
+
+ if (t == "t") { // any flavor of text returns as is
+ ;
+ }
+ else if (t == "n") {
+ operandinfo.value = SocialCalc.format_number_for_display ?
+ SocialCalc.format_number_for_display(operandinfo.value, operandinfo.type, "") :
+ operandinfo.value = operandinfo.value+"";
+ operandinfo.type = "t";
+ }
+ else if (t == "b") { // blank
+ operandinfo.value = "";
+ operandinfo.type = "t";
+ }
+ else if (t == "e") { // error
+ operandinfo.value = "";
+ }
+ else {
+ operand.value = operandinfo.value + "";
+ operand.type = "t";
+ }
+
+ return operandinfo;
+
+ }
+
+/*
+#
+# result = SocialCalc.Formula.OperandValueAndType(sheet, operand)
+#
+# Pops the top of stack and returns it, following a coord reference if necessary.
+# The result is {value: value, type: type, error: "only if bad error"}
+# Ranges are returned as if they were pushed onto the stack first coord first
+# Also sets type with "t", "n", "th", etc., as appropriate
+#
+*/
+
+SocialCalc.Formula.OperandValueAndType = function(sheet, operand) {
+
+ var cellvtype, cell, pos, coordsheet;
+ var scf = SocialCalc.Formula;
+
+ var result = {type: "", value: ""};
+
+ var stacklen = operand.length;
+
+ if (!stacklen) { // make sure something is there
+ result.error = SocialCalc.Constants.s_InternalError+"no operand on stack";
+ return result;
+ }
+
+ result.value = operand[stacklen-1].value; // get top of stack
+ result.type = operand[stacklen-1].type;
+ operand.pop(); // we have data - pop stack
+
+ if (result.type == "name") {
+ result = scf.LookupName(sheet, result.value);
+ }
+
+ if (result.type == "range") {
+ result = scf.StepThroughRangeDown(operand, result.value);
+ }
+
+ if (result.type == "coord") { // value is a coord reference
+ coordsheet = sheet;
+ pos = result.value.indexOf("!");
+ if (pos != -1) { // sheet reference
+ coordsheet = scf.FindInSheetCache(result.value.substring(pos+1)); // get other sheet
+ if (coordsheet == null) { // unavailable
+ result.type = "e#REF!";
+ result.error = SocialCalc.Constants.s_sheetunavailable+" "+result.value.substring(pos+1);
+ result.value = 0;
+ return result;
+ }
+ result.value = result.value.substring(0, pos); // get coord part
+ }
+
+ if (coordsheet) {
+ cell = coordsheet.cells[SocialCalc.Formula.PlainCoord(result.value)];
+ if (cell) {
+ cellvtype = cell.valuetype; // get type of value in the cell it points to
+ result.value = cell.datavalue;
+ }
+ else {
+ cellvtype = "b";
+ }
+ }
+ else {
+ cellvtype = "e#N/A";
+ result.value = 0;
+ }
+ result.type = cellvtype || "b";
+ if (result.type == "b") { // blank
+ result.value = 0;
+ }
+ }
+
+ return result;
+
+ }
+
+/*
+#
+# operandinfo = SocialCalc.Formula.OperandAsCoord(sheet, operand)
+#
+# Gets top of stack and pops it.
+# Returns coord value. All others are treated as an error.
+#
+*/
+
+
+SocialCalc.Formula.OperandAsCoord = function(sheet, operand) {
+
+ var scf = SocialCalc.Formula;
+
+ var result = {type: "", value: ""};
+
+ var stacklen = operand.length;
+
+ result.value = operand[stacklen-1].value; // get top of stack
+ result.type = operand[stacklen-1].type;
+ operand.pop(); // we have data - pop stack
+ if (result.type == "name") {
+ result = SocialCalc.Formula.LookupName(sheet, result.value);
+ }
+ if (result.type == "coord") { // value is a coord reference
+ return result;
+ }
+ else {
+ result.value = SocialCalc.Constants.s_calcerrcellrefmissing;
+ result.type = "e#REF!";
+ return result;
+ }
+}
+
+
+/*
+#
+# result = SocialCalc.Formula.OperandsAsCoordOnSheet(sheet, operand)
+#
+# Gets 2 at top of stack and pops them, treating them as sheetname!coord-or-name.
+# Returns stack-style coord value (coord!sheetname, or coord!sheetname|coord|) with
+# a type of coord or range. All others are treated as an error.
+# If sheetname not available, sets result.error.
+#
+*/
+
+SocialCalc.Formula.OperandsAsCoordOnSheet = function(sheet, operand) {
+
+ var sheetname, othersheet, pos1, pos2;
+ var value1 = {};
+ var result = {};
+ var scf = SocialCalc.Formula;
+
+ var stacklen = operand.length;
+ value1.value = operand[stacklen-1].value; // get top of stack - coord or name
+ value1.type = operand[stacklen-1].type;
+ operand.pop(); // we have data - pop stack
+
+ sheetname = scf.OperandAsSheetName(sheet, operand); // get sheetname as text
+ othersheet = scf.FindInSheetCache(sheetname.value);
+ if (othersheet == null) { // unavailable
+ result.type = "e#REF!";
+ result.value = 0;
+ result.error = SocialCalc.Constants.s_sheetunavailable+" "+sheetname.value;
+ return result;
+ }
+
+ if (value1.type == "name") {
+ value1 = scf.LookupName(othersheet, value1.value);
+ }
+ result.type = value1.type;
+ if (value1.type == "coord") { // value is a coord reference
+ result.value = value1.value + "!" + sheetname.value; // return in the format as used on stack
+ }
+ else if (value1.type == "range") { // value is a range reference
+ pos1 = value1.value.indexOf("|");
+ pos2 = value1.value.indexOf("|", pos1+1);
+ result.value = value1.value.substring(0, pos1) + "!" + sheetname.value +
+ "|" + value1.value.substring(pos1+1, pos2) + "|";
+ }
+ else if (value1.type.charAt(0)=="e") {
+ result.value = value1.value;
+ }
+ else {
+ result.error = SocialCalc.Constants.s_calcerrcellrefmissing;
+ result.type = "e#REF!";
+ result.value = 0;
+ }
+ return result;
+
+ }
+
+/*
+#
+# result = SocialCalc.Formula.OperandsAsRangeOnSheet(sheet, operand)
+#
+# Gets 2 at top of stack and pops them, treating them as coord2-or-name:coord1.
+# Name is evaluated on sheet of coord1.
+# Returns result with "value" of stack-style range value (coord!sheetname|coord|) and
+# "type" of "range". All others are treated as an error.
+#
+*/
+
+SocialCalc.Formula.OperandsAsRangeOnSheet = function(sheet, operand) {
+
+ var value1, othersheet, pos1, pos2;
+ var value2 = {};
+ var scf = SocialCalc.Formula;
+ var scc = SocialCalc.Constants;
+
+ var stacklen = operand.length;
+ value2.value = operand[stacklen-1].value; // get top of stack - coord or name for "right" side
+ value2.type = operand[stacklen-1].type;
+ operand.pop(); // we have data - pop stack
+
+ value1 = scf.OperandAsCoord(sheet, operand); // get "left" coord
+ if (value1.type != "coord") { // not a coord, which it must be
+ return {value: 0, type: "e#REF!"};
+ }
+
+ othersheet = sheet;
+ pos1 = value1.value.indexOf("!");
+ if (pos1 != -1) { // sheet reference
+ pos2 = value1.value.indexOf("|", pos1+1);
+ if (pos2 < 0) pos2 = value1.value.length;
+ othersheet = scf.FindInSheetCache(value1.value.substring(pos1+1,pos2)); // get other sheet
+ if (othersheet == null) { // unavailable
+ return {value: 0, type: "e#REF!", errortext: scc.s_sheetunavailable+" "+value1.value.substring(pos1+1,pos2)};
+ }
+ }
+
+ if (value2.type == "name") { // coord:name is allowed, if name is just one cell
+ value2 = scf.LookupName(othersheet, value2.value);
+ }
+
+ if (value2.type == "coord") { // value is a coord reference, so return the combined range
+ return {value: value1.value+"|"+value2.value+"|", type: "range"}; // return range in the format as used on stack
+ }
+ else { // bad form
+ return {value: scc.s_calcerrcellrefmissing, type: "e#REF!"};
+ }
+ }
+
+
+/*
+#
+# result = SocialCalc.Formula.OperandAsSheetName(sheet, operand)
+#
+# Gets top of stack and pops it.
+# Returns sheetname value. All others are treated as an error.
+# Accepts text, cell reference, and named value which is one of those two.
+#
+*/
+
+SocialCalc.Formula.OperandAsSheetName = function(sheet, operand) {
+
+ var nvalue, cell;
+
+ var scf = SocialCalc.Formula;
+
+ var result = {type: "", value: ""};
+
+ var stacklen = operand.length;
+
+ result.value = operand[stacklen-1].value; // get top of stack
+ result.type = operand[stacklen-1].type;
+ operand.pop(); // we have data - pop stack
+ if (result.type == "name") {
+ nvalue = SocialCalc.Formula.LookupName(sheet, result.value);
+ if (!nvalue.value) { // not a known name - return bare name as the name value
+ return result;
+ }
+ result.value = nvalue.value;
+ result.type = nvalue.type;
+ }
+ if (result.type == "coord") { // value is a coord reference, follow it to find sheet name
+ cell = sheet.cells[SocialCalc.Formula.PlainCoord(result.value)];
+ if (cell) {
+ result.value = cell.datavalue;
+ result.type = cell.valuetype;
+ }
+ else {
+ result.value = "";
+ result.type = "b";
+ }
+ }
+ if (result.type.charAt(0) == "t") { // value is a string which could be a sheet name
+ return result;
+ }
+ else {
+ result.value = "";
+ result.error = SocialCalc.Constants.s_calcerrsheetnamemissing;
+ return result;
+ }
+
+ }
+
+//
+// value = SocialCalc.Formula.LookupName(sheet, name)
+//
+// Returns value and type of a named value
+// Names are case insensitive
+// Names may have a definition which is a coord (A1), a range (A1:B7), or a formula (=OFFSET(A1,0,0,5,1))
+// Note: The range must not have sheet names ("!") in them.
+//
+
+SocialCalc.Formula.LookupName = function(sheet, name) {
+
+ var pos, specialc, parseinfo;
+ var names = sheet.names;
+ var value = {};
+ var startedwalk = false;
+
+ if (names[name.toUpperCase()]) { // is name defined?
+
+ value.value = names[name.toUpperCase()].definition; // yes
+
+ if (value.value.charAt(0) == "=") { // formula
+ if (!sheet.checknamecirc) { // are we possibly walking the name tree?
+ sheet.checknamecirc = {}; // not yet
+ startedwalk = true; // remember we are the reference that started it
+ }
+ else {
+ if (sheet.checknamecirc[name]) { // circular reference
+ value.type = "e#NAME?";
+ value.error = SocialCalc.Constants.s_circularnameref+' "' + name + '".';
+ return value;
+ }
+ }
+ sheet.checknamecirc[name] = true;
+
+ parseinfo = SocialCalc.Formula.ParseFormulaIntoTokens(value.value.substring(1));
+ value = SocialCalc.Formula.evaluate_parsed_formula(parseinfo, sheet, 1); // parse formula, allowing range return
+
+ delete sheet.checknamecirc[name]; // done with us
+ if (startedwalk) {
+ delete sheet.checknamecirc; // done with walk
+ }
+
+ if (value.type != "range") {
+ return value;
+ }
+ }
+
+ pos = value.value.indexOf(":");
+ if (pos != -1) { // range
+ value.type = "range";
+ value.value = value.value.substring(0, pos) + "|" + value.value.substring(pos+1)+"|";
+ value.value = value.value.toUpperCase();
+ }
+ else {
+ value.type = "coord";
+ value.value = value.value.toUpperCase();
+ }
+ return value;
+ }
+ else if (specialc=SocialCalc.Formula.SpecialConstants[name.toUpperCase()]) { // special constant, like #REF!
+ pos = specialc.indexOf(",");
+ value.value = specialc.substring(0,pos)-0;
+ value.type = specialc.substring(pos+1);
+ return value;
+ }
+ else {
+ value.value = "";
+ value.type = "e#NAME?";
+ value.error = SocialCalc.Constants.s_calcerrunknownname+' "'+name+'"';
+ return value;
+ }
+ }
+
+/*
+#
+# coord = SocialCalc.Formula.StepThroughRangeDown(operand, rangevalue)
+#
+# Returns next coord in a range, keeping track on the operand stack
+# Goes from upper left across and down to bottom right.
+#
+*/
+
+SocialCalc.Formula.StepThroughRangeDown = function(operand, rangevalue) {
+
+ var value1, value2, sequence, pos1, pos2, sheet1, rp, c, r, count;
+ var scf = SocialCalc.Formula;
+
+ pos1 = rangevalue.indexOf("|");
+ pos2 = rangevalue.indexOf("|", pos1+1);
+ value1 = rangevalue.substring(0, pos1);
+ value2 = rangevalue.substring(pos1+1, pos2);
+ sequence = rangevalue.substring(pos2+1) - 0;
+
+ pos1 = value1.indexOf("!");
+ if (pos1 != -1) {
+ sheet1 = value1.substring(pos1);
+ value1 = value1.substring(0, pos1);
+ }
+ else {
+ sheet1 = "";
+ }
+ pos1 = value2.indexOf("!");
+ if (pos1 != -1) {
+ value2 = value2.substring(0, pos1);
+ }
+
+ rp = scf.OrderRangeParts(value1, value2);
+
+ count = 0;
+ for (r=rp.r1; r<=rp.r2; r++) {
+ for (c=rp.c1; c<=rp.c2; c++) {
+ count++;
+ if (count > sequence) {
+ if (r!=rp.r2 || c!=rp.c2) { // keep on stack until done
+ scf.PushOperand(operand, "range", value1+sheet1+"|"+value2+"|"+count);
+ }
+ return {value: SocialCalc.crToCoord(c, r)+sheet1, type: "coord"};
+ }
+ }
+ }
+ }
+
+/*
+#
+# result = SocialCalc.Formula.DecodeRangeParts(sheetdata, range)
+#
+# Returns sheetdata for the sheet where the range is, as well as
+# the number of the first column in the range, the number of columns,
+# and equivalent row information:
+#
+# {sheetdata: sheet, sheetname: name-or-"", col1num: n, ncols: n, row1num: n, nrows: n}
+#
+# If any errors, a null result is returned.
+#
+*/
+
+SocialCalc.Formula.DecodeRangeParts = function(sheetdata, range) {
+
+ var value1, value2, pos1, pos2, sheet1, coordsheetdata, rp;
+
+ var scf = SocialCalc.Formula;
+
+ pos1 = range.indexOf("|");
+ pos2 = range.indexOf("|", pos1+1);
+ value1 = range.substring(0, pos1);
+ value2 = range.substring(pos1+1, pos2);
+
+ pos1 = value1.indexOf("!");
+ if (pos1 != -1) {
+ sheet1 = value1.substring(pos1+1);
+ value1 = value1.substring(0, pos1);
+ }
+ else {
+ sheet1 = "";
+ }
+ pos1 = value2.indexOf("!");
+ if (pos1 != -1) {
+ value2 = value2.substring(0, pos1);
+ }
+
+ coordsheetdata = sheetdata;
+ if (sheet1) { // sheet reference
+ coordsheetdata = scf.FindInSheetCache(sheet1);
+ if (coordsheetdata == null) { // unavailable
+ return null;
+ }
+ }
+
+ rp = scf.OrderRangeParts(value1, value2);
+
+ return {sheetdata: coordsheetdata, sheetname: sheet1, col1num: rp.c1, ncols: rp.c2-rp.c1+1, row1num: rp.r1, nrows: rp.r2-rp.r1+1}
+
+ }
+
+
+//*********************
+//
+// Function Handling
+//
+//*********************
+
+// List of functions -- Define after functions are defined
+//
+// SocialCalc.Formula.FunctionList["function_name"] = [function_subroutine, number_of_arguments, arg_def, func_def, func_class]
+// function_subroutine takes arguments (fname, operand, foperand, sheet), returns
+// errortext or null, pushing result on operand stack.
+// number_of_arguments is:
+// 0 = no arguments
+// >0 = exactly that many arguments
+// <0 = that many arguments (abs value) or more
+// 100 = don't check
+//
+// arg_def, if present, is the name of the element in SocialCalc.Formula.FunctionArgDefs.
+// func_def, if present, is a string explaining the function. If not, looked up in SocialCalc.Constants.
+// func_class, if present, is the comma-separated names of the elements in SocialCalc.Formula.FunctionClasses.
+//
+// To add a function, just add it to this object.
+
+ if (!SocialCalc.Formula.FunctionList) { // make sure it is defined (could have been in another module)
+ SocialCalc.Formula.FunctionList = {};
+ }
+
+ // FunctionClasses[classname] = {name: full-name-string, items: [sorted list of function names]};
+ // filled in by SocialCalc.Formula.FillFunctionInfo
+
+ SocialCalc.Formula.FunctionClasses = null; // start null to say needs filling in
+
+ // FunctionArgDef[argname] = explicit-string-for-arg-list;
+ // filled in by SocialCalc.Formula.FillFunctionInfo
+
+ SocialCalc.Formula.FunctionArgDefs = {};
+
+
+/*
+#
+# errortext = SocialCalc.Formula.CalculateFunction(fname, operand, sheet)
+#
+# Dispatches for function fname.
+#
+*/
+
+SocialCalc.Formula.CalculateFunction = function(fname, operand, sheet) {
+
+ var fobj, foperand, ffunc, argnum, ttext;
+ var scf = SocialCalc.Formula;
+ var ok = 1;
+ var errortext = "";
+
+ fobj = scf.FunctionList[fname];
+
+ if (fobj) {
+ foperand = [];
+ ffunc = fobj[0];
+ argnum = fobj[1];
+ scf.CopyFunctionArgs(operand, foperand);
+ if (argnum != 100) {
+ if (argnum < 0) {
+ if (foperand.length < -argnum) {
+ errortext = scf.FunctionArgsError(fname, operand);
+ return errortext;
+ }
+ }
+ else {
+ if (foperand.length != argnum) {
+ errortext = scf.FunctionArgsError(fname, operand);
+ return errortext;
+ }
+ }
+ }
+ errortext = ffunc(fname, operand, foperand, sheet);
+ }
+
+ else {
+ ttext = fname;
+
+ if (operand.length && operand[operand.length-1].type == "start") { // no arguments - name or zero arg function
+ operand.pop();
+ scf.PushOperand(operand, "name", ttext);
+ }
+
+ else {
+ errortext = SocialCalc.Constants.s_sheetfuncunknownfunction+" " + ttext +". ";
+ }
+ }
+
+ return errortext;
+
+}
+
+//
+// SocialCalc.Formula.PushOperand(operand, t, v)
+//
+// Pushes the type and value onto the operand stack
+//
+
+SocialCalc.Formula.PushOperand = function(operand, t, v) {
+
+ operand.push({type: t, value: v});
+
+ }
+
+//
+// SocialCalc.Formula.CopyFunctionArgs(operand, foperand)
+//
+// Pops operands from operand and pushes on foperand up to function start
+// reversing order in the process.
+//
+
+SocialCalc.Formula.CopyFunctionArgs = function(operand, foperand) {
+
+ var fobj, foperand, ffunc, argnum;
+ var scf = SocialCalc.Formula;
+ var ok = 1;
+ var errortext = null;
+
+ while (operand.length>0 && operand[operand.length-1].type != "start") { // get each arg
+ foperand.push(operand.pop()); // copy it
+ }
+ operand.pop(); // get rid of "start"
+
+ return;
+
+ }
+
+//
+// errortext = SocialCalc.Formula.FunctionArgsError(fname, operand)
+//
+// Pushes appropriate error on operand stack and returns errortext, including fname
+//
+
+SocialCalc.Formula.FunctionArgsError = function(fname, operand) {
+
+ var errortext = SocialCalc.Constants.s_calcerrincorrectargstofunction+" " + fname + ". ";
+ SocialCalc.Formula.PushOperand(operand, "e#VALUE!", errortext);
+
+ return errortext;
+
+ }
+
+
+//
+// errortext = SocialCalc.Formula.FunctionSpecificError(fname, operand, errortype, errortext)
+//
+// Pushes specified error and text on operand stack.
+//
+
+SocialCalc.Formula.FunctionSpecificError = function(fname, operand, errortype, errortext) {
+
+ SocialCalc.Formula.PushOperand(operand, errortype, errortext);
+
+ return errortext;
+
+ }
+
+//
+// haserror = SocialCalc.Formula.CheckForErrorValue(operand, v)
+//
+// If v.type is an error, push it on operand stack and return true, otherwise return false.
+//
+
+SocialCalc.Formula.CheckForErrorValue = function(operand, v) {
+
+ if (v.type.charAt(0) == "e") {
+ operand.push(v);
+ return true;
+ }
+ else {
+ return false;
+ }
+
+ }
+
+/////////////////////////
+//
+// FUNCTION INFORMATION ROUTINES
+//
+
+//
+// SocialCalc.Formula.FillFunctionInfo()
+//
+// Goes through function definitions and fills out FunctionArgDefs and FunctionClasses.
+// Execute this after any changes to SocialCalc.Constants but before UI is used.
+//
+
+SocialCalc.Formula.FillFunctionInfo = function() {
+
+ var scf = SocialCalc.Formula;
+ var scc = SocialCalc.Constants;
+
+ var fname, f, classes, cname, i;
+
+ if (scf.FunctionClasses) { // only do once
+ return;
+ }
+
+ for (fname in scf.FunctionList) {
+ f = scf.FunctionList[fname];
+ if (f[2]) { // has an arg def
+ scf.FunctionArgDefs[f[2]] = scc["s_farg_"+f[2]] || ""; // get it from constants
+ }
+ if (!f[3]) { // no text def, see if in constants
+ if (scc["s_fdef_"+fname]) {
+ scf.FunctionList[fname][3] = scc["s_fdef_"+fname];
+ }
+ }
+ }
+
+ scf.FunctionClasses = {};
+
+ for (i=0; i<scc.function_classlist.length; i++) {
+ cname = scc.function_classlist[i];
+ scf.FunctionClasses[cname] = {name: scc["s_fclass_"+cname], items: []};
+ }
+
+ for (fname in scf.FunctionList) {
+ f = scf.FunctionList[fname];
+ classes = f[4] ? f[4].split(",") : []; // get classes
+ classes.push("all");
+ for (i=0; i<classes.length; i++) {
+ cname = classes[i];
+ scf.FunctionClasses[cname].items.push(fname);
+ }
+ }
+ for (cname in scf.FunctionClasses) {
+ scf.FunctionClasses[cname].items.sort();
+ }
+
+ }
+
+//
+// str = SocialCalc.Formula.FunctionArgString(fname)
+//
+// Returns a string representing the arguments to function fname.
+//
+
+SocialCalc.Formula.FunctionArgString = function(fname) {
+
+ var scf = SocialCalc.Formula;
+ var fdata = scf.FunctionList[fname];
+ var nargs, i, str;
+
+ var adef = fdata[2];
+
+ if (!adef) {
+ nargs = fdata[1];
+ if (nargs == 0) {
+ adef = " ";
+ }
+ else if (nargs > 0) {
+ str = "v1";
+ for (i=2; i<=nargs; i++) {
+ str += ", v"+i;
+ }
+ return str;
+ }
+ else if (nargs < 0) {
+ str = "v1";
+ for (i=2; i<-nargs; i++) {
+ str += ", v"+i;
+ }
+ return str+", ...";
+ }
+ else {
+ return "nargs: "+nargs;
+ }
+ }
+
+ str = scf.FunctionArgDefs[adef] || adef;
+
+ return str;
+
+ }
+
+
+/////////////////////////
+//
+// FUNCTION DEFINITIONS
+//
+// The standard function definitions follow.
+//
+// Note that some need SocialCalc.DetermineValueType to be defined.
+//
+
+/*
+#
+# AVERAGE(v1,c1:c2,...)
+# COUNT(v1,c1:c2,...)
+# COUNTA(v1,c1:c2,...)
+# COUNTBLANK(v1,c1:c2,...)
+# MAX(v1,c1:c2,...)
+# MIN(v1,c1:c2,...)
+# PRODUCT(v1,c1:c2,...)
+# STDEV(v1,c1:c2,...)
+# STDEVP(v1,c1:c2,...)
+# SUM(v1,c1:c2,...)
+# VAR(v1,c1:c2,...)
+# VARP(v1,c1:c2,...)
+#
+# Calculate all of these and then return the desired one (overhead is in accessing not calculating)
+# If this routine is changed, check the dseries_functions, too.
+#
+*/
+
+SocialCalc.Formula.SeriesFunctions = function(fname, operand, foperand, sheet) {
+
+ var value1, t, v1;
+
+ var scf = SocialCalc.Formula;
+ var operand_value_and_type = scf.OperandValueAndType;
+ var lookup_result_type = scf.LookupResultType;
+ var typelookupplus = scf.TypeLookupTable.plus;
+
+ var PushOperand = function(t, v) {operand.push({type: t, value: v});};
+
+ var sum = 0;
+ var resulttypesum = "";
+ var count = 0;
+ var counta = 0;
+ var countblank = 0;
+ var product = 1;
+ var maxval;
+ var minval;
+ var mk, sk, mk1, sk1; // For variance, etc.: M sub k, k-1, and S sub k-1
+ // as per Knuth "The Art of Computer Programming" Vol. 2 3rd edition, page 232
+
+ while (foperand.length > 0) {
+ value1 = operand_value_and_type(sheet, foperand);
+ t = value1.type.charAt(0);
+ if (t == "n") count += 1;
+ if (t != "b") counta += 1;
+ if (t == "b") countblank += 1;
+
+ if (t == "n") {
+ v1 = value1.value-0; // get it as a number
+ sum += v1;
+ product *= v1;
+ maxval = (maxval!=undefined) ? (v1 > maxval ? v1 : maxval) : v1;
+ minval = (minval!=undefined) ? (v1 < minval ? v1 : minval) : v1;
+ if (count == 1) { // initialize with first values for variance used in STDEV, VAR, etc.
+ mk1 = v1;
+ sk1 = 0;
+ }
+ else { // Accumulate S sub 1 through n as per Knuth noted above
+ mk = mk1 + (v1 - mk1) / count;
+ sk = sk1 + (v1 - mk1) * (v1 - mk);
+ sk1 = sk;
+ mk1 = mk;
+ }
+ resulttypesum = lookup_result_type(value1.type, resulttypesum || value1.type, typelookupplus);
+ }
+ else if (t == "e" && resulttypesum.charAt(0) != "e") {
+ resulttypesum = value1.type;
+ }
+ }
+
+ resulttypesum = resulttypesum || "n";
+
+ switch (fname) {
+ case "SUM":
+ PushOperand(resulttypesum, sum);
+ break;
+
+ case "PRODUCT": // may handle cases with text differently than some other spreadsheets
+ PushOperand(resulttypesum, product);
+ break;
+
+ case "MIN":
+ PushOperand(resulttypesum, minval || 0);
+ break;
+
+ case "MAX":
+ PushOperand(resulttypesum, maxval || 0);
+ break;
+
+ case "COUNT":
+ PushOperand("n", count);
+ break;
+
+ case "COUNTA":
+ PushOperand("n", counta);
+ break;
+
+ case "COUNTBLANK":
+ PushOperand("n", countblank);
+ break;
+
+ case "AVERAGE":
+ if (count > 0) {
+ PushOperand(resulttypesum, sum/count);
+ }
+ else {
+ PushOperand("e#DIV/0!", 0);
+ }
+ break;
+
+ case "STDEV":
+ if (count > 1) {
+ PushOperand(resulttypesum, Math.sqrt(sk / (count - 1))); // sk is never negative according to Knuth
+ }
+ else {
+ PushOperand("e#DIV/0!", 0);
+ }
+ break;
+
+ case "STDEVP":
+ if (count > 1) {
+ PushOperand(resulttypesum, Math.sqrt(sk / count));
+ }
+ else {
+ PushOperand("e#DIV/0!", 0);
+ }
+ break;
+
+ case "VAR":
+ if (count > 1) {
+ PushOperand(resulttypesum, sk / (count - 1));
+ }
+ else {
+ PushOperand("e#DIV/0!", 0);
+ }
+ break;
+
+ case "VARP":
+ if (count > 1) {
+ PushOperand(resulttypesum, sk / count);
+ }
+ else {
+ PushOperand("e#DIV/0!", 0);
+ }
+ break;
+ }
+
+ return null;
+
+ }
+
+// Add to function list
+SocialCalc.Formula.FunctionList["AVERAGE"] = [SocialCalc.Formula.SeriesFunctions, -1, "vn", null, "stat"];
+SocialCalc.Formula.FunctionList["COUNT"] = [SocialCalc.Formula.SeriesFunctions, -1, "vn", null, "stat"];
+SocialCalc.Formula.FunctionList["COUNTA"] = [SocialCalc.Formula.SeriesFunctions, -1, "vn", null, "stat"];
+SocialCalc.Formula.FunctionList["COUNTBLANK"] = [SocialCalc.Formula.SeriesFunctions, -1, "vn", null, "stat"];
+SocialCalc.Formula.FunctionList["MAX"] = [SocialCalc.Formula.SeriesFunctions, -1, "vn", null, "stat"];
+SocialCalc.Formula.FunctionList["MIN"] = [SocialCalc.Formula.SeriesFunctions, -1, "vn", null, "stat"];
+SocialCalc.Formula.FunctionList["PRODUCT"] = [SocialCalc.Formula.SeriesFunctions, -1, "vn", null, "stat"];
+SocialCalc.Formula.FunctionList["STDEV"] = [SocialCalc.Formula.SeriesFunctions, -1, "vn", null, "stat"];
+SocialCalc.Formula.FunctionList["STDEVP"] = [SocialCalc.Formula.SeriesFunctions, -1, "vn", null, "stat"];
+SocialCalc.Formula.FunctionList["SUM"] = [SocialCalc.Formula.SeriesFunctions, -1, "vn", null, "stat"];
+SocialCalc.Formula.FunctionList["VAR"] = [SocialCalc.Formula.SeriesFunctions, -1, "vn", null, "stat"];
+SocialCalc.Formula.FunctionList["VARP"] = [SocialCalc.Formula.SeriesFunctions, -1, "vn", null, "stat"];
+
+/*
+#
+# DAVERAGE(databaserange, fieldname, criteriarange)
+# DCOUNT(databaserange, fieldname, criteriarange)
+# DCOUNTA(databaserange, fieldname, criteriarange)
+# DGET(databaserange, fieldname, criteriarange)
+# DMAX(databaserange, fieldname, criteriarange)
+# DMIN(databaserange, fieldname, criteriarange)
+# DPRODUCT(databaserange, fieldname, criteriarange)
+# DSTDEV(databaserange, fieldname, criteriarange)
+# DSTDEVP(databaserange, fieldname, criteriarange)
+# DSUM(databaserange, fieldname, criteriarange)
+# DVAR(databaserange, fieldname, criteriarange)
+# DVARP(databaserange, fieldname, criteriarange)
+#
+# Calculate all of these and then return the desired one (overhead is in accessing not calculating)
+# If this routine is changed, check the series_functions, too.
+#
+*/
+
+SocialCalc.Formula.DSeriesFunctions = function(fname, operand, foperand, sheet) {
+
+ var value1, tostype, cr, dbrange, fieldname, criteriarange, dbinfo, criteriainfo;
+ var fieldasnum, targetcol, i, j, k, cell, criteriafieldnums;
+ var testok, criteriacr, criteria, testcol, testcr;
+ var t;
+
+ var scf = SocialCalc.Formula;
+ var operand_value_and_type = scf.OperandValueAndType;
+ var lookup_result_type = scf.LookupResultType;
+ var typelookupplus = scf.TypeLookupTable.plus;
+
+ var PushOperand = function(t, v) {operand.push({type: t, value: v});};
+
+ var value1 = {};
+
+ var sum = 0;
+ var resulttypesum = "";
+ var count = 0;
+ var counta = 0;
+ var countblank = 0;
+ var product = 1;
+ var maxval;
+ var minval;
+ var mk, sk, mk1, sk1; // For variance, etc.: M sub k, k-1, and S sub k-1
+ // as per Knuth "The Art of Computer Programming" Vol. 2 3rd edition, page 232
+
+ dbrange = scf.TopOfStackValueAndType(sheet, foperand); // get a range
+ fieldname = scf.OperandValueAndType(sheet, foperand); // get a value
+ criteriarange = scf.TopOfStackValueAndType(sheet, foperand); // get a range
+
+ if (dbrange.type != "range" || criteriarange.type != "range") {
+ return scf.FunctionArgsError(fname, operand);
+ }
+
+ dbinfo = scf.DecodeRangeParts(sheet, dbrange.value);
+ criteriainfo = scf.DecodeRangeParts(sheet, criteriarange.value);
+
+ fieldasnum = scf.FieldToColnum(dbinfo.sheetdata, dbinfo.col1num, dbinfo.ncols, dbinfo.row1num, fieldname.value, fieldname.type);
+ if (fieldasnum <= 0) {
+ PushOperand("e#VALUE!", 0);
+ return;
+ }
+
+ targetcol = dbinfo.col1num + fieldasnum - 1;
+ criteriafieldnums = [];
+
+ for (i=0; i<criteriainfo.ncols; i++) { // get criteria field colnums
+ cell = criteriainfo.sheetdata.GetAssuredCell(SocialCalc.crToCoord(criteriainfo.col1num + i, criteriainfo.row1num));
+ criterianum = scf.FieldToColnum(dbinfo.sheetdata, dbinfo.col1num, dbinfo.ncols, dbinfo.row1num, cell.datavalue, cell.valuetype);
+ if (criterianum <= 0) {
+ PushOperand("e#VALUE!", 0);
+ return;
+ }
+ criteriafieldnums.push(dbinfo.col1num + criterianum - 1);
+ }
+
+ for (i=1; i<dbinfo.nrows; i++) { // go through each row of the database
+ testok = false;
+CRITERIAROW:
+ for (j=1; j<criteriainfo.nrows; j++) { // go through each criteria row
+ for (k=0; k<criteriainfo.ncols; k++) { // look at each column
+ criteriacr = SocialCalc.crToCoord(criteriainfo.col1num + k, criteriainfo.row1num + j); // where criteria is
+ cell = criteriainfo.sheetdata.GetAssuredCell(criteriacr);
+ criteria = cell.datavalue;
+ if (typeof criteria == "string" && criteria.length == 0) continue; // blank items are OK
+ testcol = criteriafieldnums[k];
+ testcr = SocialCalc.crToCoord(testcol, dbinfo.row1num + i); // cell to check
+ cell = criteriainfo.sheetdata.GetAssuredCell(testcr);
+ if (!scf.TestCriteria(cell.datavalue, cell.valuetype || "b", criteria)) {
+ continue CRITERIAROW; // does not meet criteria - check next row
+ }
+ }
+ testok = true; // met all the criteria
+ break CRITERIAROW;
+ }
+ if (!testok) {
+ continue;
+ }
+
+ cr = SocialCalc.crToCoord(targetcol, dbinfo.row1num + i); // get cell of this row to do the function on
+ cell = dbinfo.sheetdata.GetAssuredCell(cr);
+
+ value1.value = cell.datavalue;
+ value1.type = cell.valuetype;
+ t = value1.type.charAt(0);
+ if (t == "n") count += 1;
+ if (t != "b") counta += 1;
+ if (t == "b") countblank += 1;
+
+ if (t == "n") {
+ v1 = value1.value-0; // get it as a number
+ sum += v1;
+ product *= v1;
+ maxval = (maxval!=undefined) ? (v1 > maxval ? v1 : maxval) : v1;
+ minval = (minval!=undefined) ? (v1 < minval ? v1 : minval) : v1;
+ if (count == 1) { // initialize with first values for variance used in STDEV, VAR, etc.
+ mk1 = v1;
+ sk1 = 0;
+ }
+ else { // Accumulate S sub 1 through n as per Knuth noted above
+ mk = mk1 + (v1 - mk1) / count;
+ sk = sk1 + (v1 - mk1) * (v1 - mk);
+ sk1 = sk;
+ mk1 = mk;
+ }
+ resulttypesum = lookup_result_type(value1.type, resulttypesum || value1.type, typelookupplus);
+ }
+ else if (t == "e" && resulttypesum.charAt(0) != "e") {
+ resulttypesum = value1.type;
+ }
+ }
+
+ resulttypesum = resulttypesum || "n";
+
+ switch (fname) {
+ case "DSUM":
+ PushOperand(resulttypesum, sum);
+ break;
+
+ case "DPRODUCT": // may handle cases with text differently than some other spreadsheets
+ PushOperand(resulttypesum, product);
+ break;
+
+ case "DMIN":
+ PushOperand(resulttypesum, minval || 0);
+ break;
+
+ case "DMAX":
+ PushOperand(resulttypesum, maxval || 0);
+ break;
+
+ case "DCOUNT":
+ PushOperand("n", count);
+ break;
+
+ case "DCOUNTA":
+ PushOperand("n", counta);
+ break;
+
+ case "DAVERAGE":
+ if (count > 0) {
+ PushOperand(resulttypesum, sum/count);
+ }
+ else {
+ PushOperand("e#DIV/0!", 0);
+ }
+ break;
+
+ case "DSTDEV":
+ if (count > 1) {
+ PushOperand(resulttypesum, Math.sqrt(sk / (count - 1))); // sk is never negative according to Knuth
+ }
+ else {
+ PushOperand("e#DIV/0!", 0);
+ }
+ break;
+
+ case "DSTDEVP":
+ if (count > 1) {
+ PushOperand(resulttypesum, Math.sqrt(sk / count));
+ }
+ else {
+ PushOperand("e#DIV/0!", 0);
+ }
+ break;
+
+ case "DVAR":
+ if (count > 1) {
+ PushOperand(resulttypesum, sk / (count - 1));
+ }
+ else {
+ PushOperand("e#DIV/0!", 0);
+ }
+ break;
+
+ case "DVARP":
+ if (count > 1) {
+ PushOperand(resulttypesum, sk / count);
+ }
+ else {
+ PushOperand("e#DIV/0!", 0);
+ }
+ break;
+
+ case "DGET":
+ if (count == 1) {
+ PushOperand(resulttypesum, sum);
+ }
+ else if (count == 0) {
+ PushOperand("e#VALUE!", 0);
+ }
+ else {
+ PushOperand("e#NUM!", 0);
+ }
+ break;
+
+ }
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["DAVERAGE"] = [SocialCalc.Formula.DSeriesFunctions, 3, "dfunc", "", "stat"];
+SocialCalc.Formula.FunctionList["DCOUNT"] = [SocialCalc.Formula.DSeriesFunctions, 3, "dfunc", "", "stat"];
+SocialCalc.Formula.FunctionList["DCOUNTA"] = [SocialCalc.Formula.DSeriesFunctions, 3, "dfunc", "", "stat"];
+SocialCalc.Formula.FunctionList["DGET"] = [SocialCalc.Formula.DSeriesFunctions, 3, "dfunc", "", "stat"];
+SocialCalc.Formula.FunctionList["DMAX"] = [SocialCalc.Formula.DSeriesFunctions, 3, "dfunc", "", "stat"];
+SocialCalc.Formula.FunctionList["DMIN"] = [SocialCalc.Formula.DSeriesFunctions, 3, "dfunc", "", "stat"];
+SocialCalc.Formula.FunctionList["DPRODUCT"] = [SocialCalc.Formula.DSeriesFunctions, 3, "dfunc", "", "stat"];
+SocialCalc.Formula.FunctionList["DSTDEV"] = [SocialCalc.Formula.DSeriesFunctions, 3, "dfunc", "", "stat"];
+SocialCalc.Formula.FunctionList["DSTDEVP"] = [SocialCalc.Formula.DSeriesFunctions, 3, "dfunc", "", "stat"];
+SocialCalc.Formula.FunctionList["DSUM"] = [SocialCalc.Formula.DSeriesFunctions, 3, "dfunc", "", "stat"];
+SocialCalc.Formula.FunctionList["DVAR"] = [SocialCalc.Formula.DSeriesFunctions, 3, "dfunc", "", "stat"];
+SocialCalc.Formula.FunctionList["DVARP"] = [SocialCalc.Formula.DSeriesFunctions, 3, "dfunc", "", "stat"];
+
+/*
+#
+# colnum = SocialCalc.Formula.FieldToColnum(sheet, col1num, ncols, row1num, fieldname, fieldtype)
+#
+# If fieldname is a number, uses it, otherwise looks up string in cells in row to find field number
+#
+# If not found, returns 0.
+#
+*/
+
+SocialCalc.Formula.FieldToColnum = function(sheet, col1num, ncols, row1num, fieldname, fieldtype) {
+
+ var colnum, cell, value;
+
+ if (fieldtype.charAt(0) == "n") { // number - return it if legal
+ colnum = fieldname - 0; // make sure a number
+ if (colnum <= 0 || colnum > ncols) {
+ return 0;
+ }
+ return Math.floor(colnum);
+ }
+
+ if (fieldtype.charAt(0) != "t") { // must be text otherwise
+ return 0;
+ }
+
+ fieldname = fieldname ? fieldname.toLowerCase() : "";
+
+ for (colnum=0; colnum < ncols; colnum++) { // look through column headers for a match
+ cell = sheet.GetAssuredCell(SocialCalc.crToCoord(col1num+colnum, row1num));
+ value = cell.datavalue;
+ value = (value+"").toLowerCase(); // ignore case
+ if (value == fieldname) { // match
+ return colnum+1;
+ }
+ }
+ return 0; // looked at all and no match
+
+ }
+
+
+/*
+#
+# HLOOKUP(value, range, row, [rangelookup])
+# VLOOKUP(value, range, col, [rangelookup])
+# MATCH(value, range, [rangelookup])
+#
+*/
+
+SocialCalc.Formula.LookupFunctions = function(fname, operand, foperand, sheet) {
+
+ var lookupvalue, range, offset, rangelookup, offsetvalue, rangeinfo;
+ var c, r, cincr, rincr, previousOK, csave, rsave, cell, value, valuetype, cr, lookupvalue;
+
+ var scf = SocialCalc.Formula;
+ var operand_value_and_type = scf.OperandValueAndType;
+ var lookup_result_type = scf.LookupResultType;
+ var typelookupplus = scf.TypeLookupTable.plus;
+
+ var PushOperand = function(t, v) {operand.push({type: t, value: v});};
+
+ lookupvalue = operand_value_and_type(sheet, foperand);
+ if (typeof lookupvalue.value == "string") {
+ lookupvalue.value = lookupvalue.value.toLowerCase();
+ }
+
+ range = scf.TopOfStackValueAndType(sheet, foperand);
+
+ rangelookup = 1; // default to true or 1
+ if (fname == "MATCH") {
+ if (foperand.length) {
+ rangelookup = scf.OperandAsNumber(sheet, foperand);
+ if (rangelookup.type.charAt(0) != "n") {
+ PushOperand("e#VALUE!", 0);
+ return;
+ }
+ if (foperand.length) {
+ scf.FunctionArgsError(fname, operand);
+ return 0;
+ }
+ rangelookup = rangelookup.value - 0;
+ }
+ }
+ else {
+ offsetvalue = scf.OperandAsNumber(sheet, foperand);
+ if (offsetvalue.type.charAt(0) != "n") {
+ PushOperand("e#VALUE!", 0);
+ return;
+ }
+ offsetvalue = Math.floor(offsetvalue.value);
+ if (foperand.length) {
+ rangelookup = scf.OperandAsNumber(sheet, foperand);
+ if (rangelookup.type.charAt(0) != "n") {
+ PushOperand("e#VALUE!", 0);
+ return;
+ }
+ if (foperand.length) {
+ scf.FunctionArgsError(fname, operand);
+ return 0;
+ }
+ rangelookup = rangelookup.value ? 1 : 0; // convert to 1 or 0
+ }
+ }
+ lookupvalue.type = lookupvalue.type.charAt(0); // only deal with general type
+ if (lookupvalue.type == "n") { // if number, make sure a number
+ lookupvalue.value = lookupvalue.value - 0;
+ }
+
+ if (range.type != "range") {
+ scf.FunctionArgsError(fname, operand);
+ return 0;
+ }
+
+ rangeinfo = scf.DecodeRangeParts(sheet, range.value, range.type);
+ if (!rangeinfo) {
+ PushOperand("e#REF!", 0);
+ return;
+ }
+
+ c = 0;
+ r = 0;
+ cincr = 0;
+ rincr = 0;
+ if (fname == "HLOOKUP") {
+ cincr = 1;
+ if (offsetvalue > rangeinfo.nrows) {
+ PushOperand("e#REF!", 0);
+ return;
+ }
+ }
+ else if (fname == "VLOOKUP") {
+ rincr = 1;
+ if (offsetvalue > rangeinfo.ncols) {
+ PushOperand("e#REF!", 0);
+ return;
+ }
+ }
+ else if (fname == "MATCH") {
+ if (rangeinfo.ncols > 1) {
+ if (rangeinfo.nrows > 1) {
+ PushOperand("e#N/A", 0);
+ return;
+ }
+ cincr = 1;
+ }
+ else {
+ rincr = 1;
+ }
+ }
+ else {
+ scf.FunctionArgsError(fname, operand);
+ return 0;
+ }
+ if (offsetvalue < 1 && fname != "MATCH") {
+ PushOperand("e#VALUE!", 0);
+ return 0;
+ }
+
+ previousOK; // if 1, previous test was <. If 2, also this one wasn't
+
+ while (1) {
+ cr = SocialCalc.crToCoord(rangeinfo.col1num + c, rangeinfo.row1num + r);
+ cell = rangeinfo.sheetdata.GetAssuredCell(cr);
+ value = cell.datavalue;
+ valuetype = cell.valuetype ? cell.valuetype.charAt(0) : "b"; // only deal with general types
+ if (valuetype == "n") {
+ value = value - 0; // make sure number
+ }
+ if (rangelookup) { // rangelookup type 1 or -1: look for within brackets for matches
+ if (lookupvalue.type == "n" && valuetype == "n") {
+ if (lookupvalue.value == value) { // match
+ break;
+ }
+ if ((rangelookup > 0 && lookupvalue.value > value)
+ || (rangelookup < 0 && lookupvalue.value < value)) { // possible match: wait and see
+ previousOK = 1;
+ csave = c; // remember col and row of last OK
+ rsave = r;
+ }
+ else if (previousOK) { // last one was OK, this one isn't
+ previousOK = 2;
+ break;
+ }
+ }
+
+ else if (lookupvalue.type == "t" && valuetype == "t") {
+ value = typeof value == "string" ? value.toLowerCase() : "";
+ if (lookupvalue.value == value) { // match
+ break;
+ }
+ if ((rangelookup > 0 && lookupvalue.value > value)
+ || (rangelookup < 0 && lookupvalue.value < value)) { // possible match: wait and see
+ previousOK = 1;
+ csave = c;
+ rsave = r;
+ }
+ else if (previousOK) { // last one was OK, this one isn't
+ previousOK = 2;
+ break;
+ }
+ }
+ }
+ else { // exact value matches
+ if (lookupvalue.type == "n" && valuetype == "n") {
+ if (lookupvalue.value == value) { // match
+ break;
+ }
+ }
+ else if (lookupvalue.type == "t" && valuetype == "t") {
+ value = typeof value == "string" ? value.toLowerCase() : "";
+ if (lookupvalue.value == value) { // match
+ break;
+ }
+ }
+ }
+
+ r += rincr;
+ c += cincr;
+ if (r >= rangeinfo.nrows || c >= rangeinfo.ncols) { // end of range to check, no exact match
+ if (previousOK) { // at least one could have been OK
+ previousOK = 2;
+ break;
+ }
+ PushOperand("e#N/A", 0);
+ return;
+ }
+ }
+
+ if (previousOK == 2) { // back to last OK
+ r = rsave;
+ c = csave;
+ }
+
+ if (fname == "MATCH") {
+ value = c + r + 1; // only one may be <> 0
+ valuetype = "n";
+ }
+ else {
+ cr = SocialCalc.crToCoord(rangeinfo.col1num+c+(fname == "VLOOKUP" ? offsetvalue-1 : 0), rangeinfo.row1num+r+(fname == "HLOOKUP" ? offsetvalue-1 : 0));
+ cell = rangeinfo.sheetdata.GetAssuredCell(cr);
+ value = cell.datavalue;
+ valuetype = cell.valuetype;
+ }
+ PushOperand(valuetype, value);
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["HLOOKUP"] = [SocialCalc.Formula.LookupFunctions, -3, "hlookup", "", "lookup"];
+SocialCalc.Formula.FunctionList["MATCH"] = [SocialCalc.Formula.LookupFunctions, -2, "match", "", "lookup"];
+SocialCalc.Formula.FunctionList["VLOOKUP"] = [SocialCalc.Formula.LookupFunctions, -3, "vlookup", "", "lookup"];
+
+/*
+#
+# INDEX(range, rownum, colnum)
+#
+*/
+
+SocialCalc.Formula.IndexFunction = function(fname, operand, foperand, sheet) {
+
+ var range, sheetname, indexinfo, rowindex, colindex, result, resulttype;
+
+ var scf = SocialCalc.Formula;
+
+ var PushOperand = function(t, v) {operand.push({type: t, value: v});};
+
+ range = scf.TopOfStackValueAndType(sheet, foperand); // get range
+ if (range.type != "range") {
+ scf.FunctionArgsError(fname, operand);
+ return 0;
+ }
+ indexinfo = scf.DecodeRangeParts(sheet, range.value, range.type);
+ if (indexinfo.sheetname) {
+ sheetname = "!" + indexinfo.sheetname;
+ }
+ else {
+ sheetname = "";
+ }
+
+ rowindex = {value:0};
+ colindex = {value:0};
+
+ if (foperand.length) { // look for row number
+ rowindex = scf.OperandAsNumber(sheet, foperand);
+ if (rowindex.type.charAt(0) != "n" || rowindex.value < 0) {
+ PushOperand("e#VALUE!", 0);
+ return;
+ }
+ if (foperand.length) { // look for col number
+ colindex = scf.OperandAsNumber(sheet, foperand);
+ if (colindex.type.charAt(0) != "n" || colindex.value < 0) {
+ PushOperand("e#VALUE!", 0);
+ return;
+ }
+ if (foperand.length) {
+ scf.FunctionArgsError(fname, operand);
+ return 0;
+ }
+ }
+ else { // col number missing
+ if (indexinfo.nrows == 1) { // if only one row, then rowindex is really colindex
+ colindex.value = rowindex.value;
+ rowindex.value = 0;
+ }
+ }
+ }
+
+ if (rowindex.value > indexinfo.nrows || colindex.value > indexinfo.ncols) {
+ PushOperand("e#REF!", 0);
+ return;
+ }
+
+ if (rowindex.value == 0) {
+ if (colindex.value == 0) {
+ if (indexinfo.nrows == 1 && indexinfo.ncols == 1) {
+ result = SocialCalc.crToCoord(indexinfo.col1num, indexinfo.row1num) + sheetname;
+ resulttype = "coord";
+ }
+ else {
+ result = SocialCalc.crToCoord(indexinfo.col1num, indexinfo.row1num) + sheetname + "|" +
+ SocialCalc.crToCoord(indexinfo.col1num+indexinfo.ncols-1, indexinfo.row1num+indexinfo.nrows-1) +
+ "|";
+ resulttype = "range";
+ }
+ }
+ else {
+ if (indexinfo.nrows == 1) {
+ result = SocialCalc.crToCoord(indexinfo.col1num+colindex.value-1, indexinfo.row1num) + sheetname;
+ resulttype = "coord";
+ }
+ else {
+ result = SocialCalc.crToCoord(indexinfo.col1num+colindex.value-1, indexinfo.row1num) + sheetname + "|" +
+ SocialCalc.crToCoord(indexinfo.col1num+colindex.value-1, indexinfo.row1num+indexinfo.nrows-1) +
+ "|";
+ resulttype = "range";
+ }
+ }
+ }
+ else {
+ if (colindex.value == 0) {
+ if (indexinfo.ncols == 1) {
+ result = SocialCalc.crToCoord(indexinfo.col1num, indexinfo.row1num+rowindex.value-1) + sheetname;
+ resulttype = "coord";
+ }
+ else {
+ result = SocialCalc.crToCoord(indexinfo.col1num, indexinfo.row1num+rowindex.value-1) + sheetname + "|" +
+ SocialCalc.crToCoord(indexinfo.col1num+indexinfo.ncols-1, indexinfo.row1num+rowindex.value-1) +
+ "|";
+ resulttype = "range";
+ }
+ }
+ else {
+ result = SocialCalc.crToCoord(indexinfo.col1num+colindex.value-1, indexinfo.row1num+rowindex.value-1) + sheetname;
+ resulttype = "coord";
+ }
+ }
+
+ PushOperand(resulttype, result);
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["INDEX"] = [SocialCalc.Formula.IndexFunction, -1, "index", "", "lookup"];
+
+/*
+#
+# COUNTIF(c1:c2,"criteria")
+# SUMIF(c1:c2,"criteria",[range2])
+#
+*/
+
+SocialCalc.Formula.CountifSumifFunctions = function(fname, operand, foperand, sheet) {
+
+ var range, criteria, sumrange, f2operand, result, resulttype, value1, value2;
+ var sum = 0;
+ var resulttypesum = "";
+ var count = 0;
+
+ var scf = SocialCalc.Formula;
+ var operand_value_and_type = scf.OperandValueAndType;
+ var lookup_result_type = scf.LookupResultType;
+ var typelookupplus = scf.TypeLookupTable.plus;
+
+ var PushOperand = function(t, v) {operand.push({type: t, value: v});};
+
+ range = scf.TopOfStackValueAndType(sheet, foperand); // get range or coord
+ criteria = scf.OperandAsText(sheet, foperand); // get criteria
+ if (fname == "SUMIF") {
+ if (foperand.length == 1) { // three arg form of SUMIF
+ sumrange = scf.TopOfStackValueAndType(sheet, foperand);
+ }
+ else if (foperand.length == 0) { // two arg form
+ sumrange = {value: range.value, type: range.type};
+ }
+ else {
+ scf.FunctionArgsError(fname, operand);
+ return 0;
+ }
+ }
+ else {
+ sumrange = {value: range.value, type: range.type};
+ }
+
+ if (criteria.type.charAt(0) == "n") {
+ criteria.value = criteria.value + ""; // make text
+ }
+ else if (criteria.type.charAt(0) == "e") { // error
+ criteria.value = null;
+ }
+ else if (criteria.type.charAt(0) == "b") { // blank here is undefined
+ criteria.value = null;
+ }
+
+ if (range.type != "coord" && range.type != "range") {
+ scf.FunctionArgsError(fname, operand);
+ return 0;
+ }
+
+ if (fname == "SUMIF" && sumrange.type != "coord" && sumrange.type != "range") {
+ scf.FunctionArgsError(fname, operand);
+ return 0;
+ }
+
+ foperand.push(range);
+ f2operand = []; // to allow for 3 arg form
+ f2operand.push(sumrange);
+
+ while (foperand.length) {
+ value1 = operand_value_and_type(sheet, foperand);
+ value2 = operand_value_and_type(sheet, f2operand);
+
+ if (!scf.TestCriteria(value1.value, value1.type, criteria.value)) {
+ continue;
+ }
+
+ count += 1;
+
+ if (value2.type.charAt(0) == "n") {
+ sum += value2.value-0;
+ resulttypesum = lookup_result_type(value2.type, resulttypesum || value2.type, typelookupplus);
+ }
+ else if (value2.type.charAt(0) == "e" && resulttypesum.charAt(0) != "e") {
+ resulttypesum = value2.type;
+ }
+ }
+
+ resulttypesum = resulttypesum || "n";
+
+ if (fname == "SUMIF") {
+ PushOperand(resulttypesum, sum);
+ }
+ else if (fname == "COUNTIF") {
+ PushOperand("n", count);
+ }
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["COUNTIF"] = [SocialCalc.Formula.CountifSumifFunctions, 2, "rangec", "", "stat"];
+SocialCalc.Formula.FunctionList["SUMIF"] = [SocialCalc.Formula.CountifSumifFunctions, -2, "sumif", "", "stat"];
+
+/*
+#
+# IF(cond,truevalue,falsevalue)
+#
+*/
+
+SocialCalc.Formula.IfFunction = function(fname, operand, foperand, sheet) {
+
+ var cond, t;
+
+ cond = SocialCalc.Formula.OperandValueAndType(sheet, foperand);
+ t = cond.type.charAt(0);
+ if (t != "n" && t != "b") {
+ operand.push({type: "e#VALUE!", value: 0});
+ return;
+ }
+
+ if (!cond.value) foperand.pop();
+ operand.push(foperand.pop());
+ if (cond.value) foperand.pop();
+
+ return null;
+
+ }
+
+// Add to function list
+SocialCalc.Formula.FunctionList["IF"] = [SocialCalc.Formula.IfFunction, 3, "iffunc", "", "test"];
+
+/*
+#
+# DATE(year,month,day)
+#
+*/
+
+SocialCalc.Formula.DateFunction = function(fname, operand, foperand, sheet) {
+
+ var scf = SocialCalc.Formula;
+ var result = 0;
+ var year = scf.OperandAsNumber(sheet, foperand);
+ var month = scf.OperandAsNumber(sheet, foperand);
+ var day = scf.OperandAsNumber(sheet, foperand);
+ var resulttype = scf.LookupResultType(year.type, month.type, scf.TypeLookupTable.twoargnumeric);
+ resulttype = scf.LookupResultType(resulttype, day.type, scf.TypeLookupTable.twoargnumeric);
+ if (resulttype.charAt(0) == "n") {
+ result = SocialCalc.FormatNumber.convert_date_gregorian_to_julian(
+ Math.floor(year.value), Math.floor(month.value), Math.floor(day.value)
+ ) - SocialCalc.FormatNumber.datevalues.julian_offset;
+ resulttype = "nd";
+ }
+ scf.PushOperand(operand, resulttype, result);
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["DATE"] = [SocialCalc.Formula.DateFunction, 3, "date", "", "datetime"];
+
+/*
+#
+# TIME(hour,minute,second)
+#
+*/
+
+SocialCalc.Formula.TimeFunction = function(fname, operand, foperand, sheet) {
+
+ var scf = SocialCalc.Formula;
+ var result = 0;
+ var hours = scf.OperandAsNumber(sheet, foperand);
+ var minutes = scf.OperandAsNumber(sheet, foperand);
+ var seconds = scf.OperandAsNumber(sheet, foperand);
+ var resulttype = scf.LookupResultType(hours.type, minutes.type, scf.TypeLookupTable.twoargnumeric);
+ resulttype = scf.LookupResultType(resulttype, seconds.type, scf.TypeLookupTable.twoargnumeric);
+ if (resulttype.charAt(0) == "n") {
+ result = ((hours.value * 60 * 60) + (minutes.value * 60) + seconds.value) / (24*60*60);
+ resulttype = "nt";
+ }
+ scf.PushOperand(operand, resulttype, result);
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["TIME"] = [SocialCalc.Formula.TimeFunction, 3, "hms", "", "datetime"];
+
+/*
+#
+# DAY(date)
+# MONTH(date)
+# YEAR(date)
+# WEEKDAY(date, [type])
+#
+*/
+
+SocialCalc.Formula.DMYFunctions = function(fname, operand, foperand, sheet) {
+
+ var ymd, dtype, doffset;
+ var scf = SocialCalc.Formula;
+ var result = 0;
+
+ var datevalue = scf.OperandAsNumber(sheet, foperand);
+ var resulttype = scf.LookupResultType(datevalue.type, datevalue.type, scf.TypeLookupTable.oneargnumeric);
+
+ if (resulttype.charAt(0) == "n") {
+ ymd = SocialCalc.FormatNumber.convert_date_julian_to_gregorian(
+ Math.floor(datevalue.value + SocialCalc.FormatNumber.datevalues.julian_offset));
+ switch (fname) {
+ case "DAY":
+ result = ymd.day;
+ break;
+
+ case "MONTH":
+ result = ymd.month;
+ break;
+
+ case "YEAR":
+ result = ymd.year;
+ break;
+
+ case "WEEKDAY":
+ dtype = {value: 1};
+ if (foperand.length) { // get type if present
+ dtype = scf.OperandAsNumber(sheet, foperand);
+ if (dtype.type.charAt(0) != "n" || dtype.value < 1 || dtype.value > 3) {
+ scf.PushOperand(operand, "e#VALUE!", 0);
+ return;
+ }
+ if (foperand.length) { // extra args
+ scf.FunctionArgsError(fname, operand);
+ return;
+ }
+ }
+ doffset = 6;
+ if (dtype.value > 1) {
+ doffset -= 1;
+ }
+ result = Math.floor(datevalue.value+doffset) % 7 + (dtype.value < 3 ? 1 : 0);
+ break;
+ }
+ }
+
+ scf.PushOperand(operand, resulttype, result);
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["DAY"] = [SocialCalc.Formula.DMYFunctions, 1, "v", "", "datetime"];
+SocialCalc.Formula.FunctionList["MONTH"] = [SocialCalc.Formula.DMYFunctions, 1, "v", "", "datetime"];
+SocialCalc.Formula.FunctionList["YEAR"] = [SocialCalc.Formula.DMYFunctions, 1, "v", "", "datetime"];
+SocialCalc.Formula.FunctionList["WEEKDAY"] = [SocialCalc.Formula.DMYFunctions, -1, "weekday", "", "datetime"];
+
+/*
+#
+# HOUR(datetime)
+# MINUTE(datetime)
+# SECOND(datetime)
+#
+*/
+
+SocialCalc.Formula.HMSFunctions = function(fname, operand, foperand, sheet) {
+
+ var hours, minutes, seconds, fraction;
+ var scf = SocialCalc.Formula;
+ var result = 0;
+
+ var datetime = scf.OperandAsNumber(sheet, foperand);
+ var resulttype = scf.LookupResultType(datetime.type, datetime.type, scf.TypeLookupTable.oneargnumeric);
+
+ if (resulttype.charAt(0) == "n") {
+ if (datetime.value < 0) {
+ scf.PushOperand(operand, "e#NUM!", 0); // must be non-negative
+ return;
+ }
+ fraction = datetime.value - Math.floor(datetime.value); // fraction of a day
+ fraction *= 24;
+ hours = Math.floor(fraction);
+ fraction -= Math.floor(fraction);
+ fraction *= 60;
+ minutes = Math.floor(fraction);
+ fraction -= Math.floor(fraction);
+ fraction *= 60;
+ seconds = Math.floor(fraction + (datetime.value >= 0 ? 0.5: -0.5));
+ if (fname == "HOUR") {
+ result = hours;
+ }
+ else if (fname == "MINUTE") {
+ result = minutes;
+ }
+ else if (fname == "SECOND") {
+ result = seconds;
+ }
+ }
+
+ scf.PushOperand(operand, resulttype, result);
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["HOUR"] = [SocialCalc.Formula.HMSFunctions, 1, "v", "", "datetime"];
+SocialCalc.Formula.FunctionList["MINUTE"] = [SocialCalc.Formula.HMSFunctions, 1, "v", "", "datetime"];
+SocialCalc.Formula.FunctionList["SECOND"] = [SocialCalc.Formula.HMSFunctions, 1, "v", "", "datetime"];
+
+/*
+#
+# EXACT(v1,v2)
+#
+*/
+
+SocialCalc.Formula.ExactFunction = function(fname, operand, foperand, sheet) {
+
+ var scf = SocialCalc.Formula;
+ var result = 0;
+ var resulttype = "nl";
+
+ var value1 = scf.OperandValueAndType(sheet, foperand);
+ var v1type = value1.type.charAt(0);
+ var value2 = scf.OperandValueAndType(sheet, foperand);
+ var v2type = value2.type.charAt(0);
+
+ if (v1type == "t") {
+ if (v2type == "t") {
+ result = value1.value == value2.value ? 1 : 0;
+ }
+ else if (v2type == "b") {
+ result = value1.value.length ? 0 : 1;
+ }
+ else if (v2type == "n") {
+ result = value1.value == value2.value+"" ? 1 : 0;
+ }
+ else if (v2type == "e") {
+ result = value2.value;
+ resulttype = value2.type;
+ }
+ else {
+ result = 0;
+ }
+ }
+ else if (v1type == "n") {
+ if (v2type == "n") {
+ result = value1.value-0 == value2.value-0 ? 1 : 0;
+ }
+ else if (v2type == "b") {
+ result = 0;
+ }
+ else if (v2type == "t") {
+ result = value1.value+"" == value2.value ? 1 : 0;
+ }
+ else if (v2type == "e") {
+ result = value2.value;
+ resulttype = value2.type;
+ }
+ else {
+ result = 0;
+ }
+ }
+ else if (v1type == "b") {
+ if (v2type == "t") {
+ result = value2.value.length ? 0 : 1;
+ }
+ else if (v2type == "b") {
+ result = 1;
+ }
+ else if (v2type == "n") {
+ result = 0;
+ }
+ else if (v2type == "e") {
+ result = value2.value;
+ resulttype = value2.type;
+ }
+ else {
+ result = 0;
+ }
+ }
+ else if (v1type == "e") {
+ result = value1.value;
+ resulttype = value1.type;
+ }
+
+ scf.PushOperand(operand, resulttype, result);
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["EXACT"] = [SocialCalc.Formula.ExactFunction, 2, "", "", "text"];
+
+/*
+#
+# FIND(key,string,[start])
+# LEFT(string,[length])
+# LEN(string)
+# LOWER(string)
+# MID(string,start,length)
+# PROPER(string)
+# REPLACE(string,start,length,new)
+# REPT(string,count)
+# RIGHT(string,[length])
+# SUBSTITUTE(string,old,new,[which])
+# TRIM(string)
+# UPPER(string)
+#
+*/
+
+// SocialCalc.Formula.ArgList has an array for each function, one entry for each possible arg (up to max).
+// Min args are specified in SocialCalc.Formula.FunctionList.
+// If array element is 1 then it's a text argument, if it's 0 then it's numeric, if -1 then just get whatever's there
+// Text values are manipulated as UTF-8, converting from and back to byte strings
+
+SocialCalc.Formula.ArgList = {
+ FIND: [1, 1, 0],
+ LEFT: [1, 0],
+ LEN: [1],
+ LOWER: [1],
+ MID: [1, 0, 0],
+ PROPER: [1],
+ REPLACE: [1, 0, 0, 1],
+ REPT: [1, 0],
+ RIGHT: [1, 0],
+ SUBSTITUTE: [1, 1, 1, 0],
+ TRIM: [1],
+ UPPER: [1]
+ };
+
+SocialCalc.Formula.StringFunctions = function(fname, operand, foperand, sheet) {
+
+ var i, value, offset, len, start, count;
+ var scf = SocialCalc.Formula;
+ var result = 0;
+ var resulttype = "e#VALUE!";
+
+ var numargs = foperand.length;
+ var argdef = scf.ArgList[fname];
+ var operand_value = [];
+ var operand_type = [];
+
+ for (i=1; i <= numargs; i++) { // go through each arg, get value and type, and check for errors
+ if (i > argdef.length) { // too many args
+ scf.FunctionArgsError(fname, operand);
+ return;
+ }
+ if (argdef[i-1] == 0) {
+ value = scf.OperandAsNumber(sheet, foperand);
+ }
+ else if (argdef[i-1] == 1) {
+ value = scf.OperandAsText(sheet, foperand);
+ }
+ else if (argdef[i-1] == -1) {
+ value = scf.OperandValueAndType(sheet, foperand);
+ }
+ operand_value[i] = value.value;
+ operand_type[i] = value.type;
+ if (value.type.charAt(0) == "e") {
+ scf.PushOperand(operand, value.type, result);
+ return;
+ }
+ }
+
+ switch (fname) {
+ case "FIND":
+ offset = operand_type[3] ? operand_value[3]-1 : 0;
+ if (offset < 0) {
+ result = "Start is before string"; // !! not displayed, no need to translate
+ }
+ else {
+ result = operand_value[2].indexOf(operand_value[1], offset); // (null string matches first char)
+ if (result >= 0) {
+ result += 1;
+ resulttype = "n";
+ }
+ else {
+ result = "Not found"; // !! not displayed, error is e#VALUE!
+ }
+ }
+ break;
+
+ case "LEFT":
+ len = operand_type[2] ? operand_value[2]-0 : 1;
+ if (len < 0) {
+ result = "Negative length";
+ }
+ else {
+ result = operand_value[1].substring(0, len);
+ resulttype = "t";
+ }
+ break;
+
+ case "LEN":
+ result = operand_value[1].length;
+ resulttype = "n";
+ break;
+
+ case "LOWER":
+ result = operand_value[1].toLowerCase();
+ resulttype = "t";
+ break;
+
+ case "MID":
+ start = operand_value[2]-0;
+ len = operand_value[3]-0;
+ if (len < 1 || start < 1) {
+ result = "Bad arguments";
+ }
+ else {
+ result = operand_value[1].substring(start-1, start+len-1);
+ resulttype = "t";
+ }
+ break;
+
+ case "PROPER":
+ result = operand_value[1].replace(/\b\w+\b/g, function(word) {
+ return word.substring(0,1).toUpperCase() +
+ word.substring(1);
+ }); // uppercase first character of words (see JavaScript, Flanagan, 5th edition, page 704)
+ resulttype = "t";
+ break;
+
+ case "REPLACE":
+ start = operand_value[2]-0;
+ len = operand_value[3]-0;
+ if (len < 0 || start < 1) {
+ result = "Bad arguments";
+ }
+ else {
+ result = operand_value[1].substring(0, start-1) + operand_value[4] +
+ operand_value[1].substring(start-1+len);
+ resulttype = "t";
+ }
+ break;
+
+ case "REPT":
+ count = operand_value[2]-0;
+ if (count < 0) {
+ result = "Negative count";
+ }
+ else {
+ result = "";
+ for (; count > 0; count--) {
+ result += operand_value[1];
+ }
+ resulttype = "t";
+ }
+ break;
+
+ case "RIGHT":
+ len = operand_type[2] ? operand_value[2]-0 : 1;
+ if (len < 0) {
+ result = "Negative length";
+ }
+ else {
+ result = operand_value[1].slice(-len);
+ resulttype = "t";
+ }
+ break;
+
+ case "SUBSTITUTE":
+ fulltext = operand_value[1];
+ oldtext = operand_value[2];
+ newtext = operand_value[3];
+ if (operand_value[4] != null) {
+ which = operand_value[4]-0;
+ if (which <= 0) {
+ result = "Non-positive instance number";
+ break;
+ }
+ }
+ else {
+ which = 0;
+ }
+ count = 0;
+ oldpos = 0;
+ result = "";
+ while (true) {
+ pos = fulltext.indexOf(oldtext, oldpos);
+ if (pos >= 0) {
+ count++; //!!!!!! old test just in case: if (count>1000) {alert(pos); break;}
+ result += fulltext.substring(oldpos, pos);
+ if (which==0) {
+ result += newtext; // substitute
+ }
+ else if (which==count) {
+ result += newtext + fulltext.substring(pos+oldtext.length);
+ break;
+ }
+ else {
+ result += oldtext; // leave as was
+ }
+ oldpos = pos + oldtext.length;
+ }
+ else { // no more
+ result += fulltext.substring(oldpos);
+ break;
+ }
+ }
+ resulttype = "t";
+ break;
+
+ case "TRIM":
+ result = operand_value[1];
+ result = result.replace(/^ */, "");
+ result = result.replace(/ *$/, "");
+ result = result.replace(/ +/g, " ");
+ resulttype = "t";
+ break;
+
+ case "UPPER":
+ result = operand_value[1].toUpperCase();
+ resulttype = "t";
+ break;
+
+ }
+
+ scf.PushOperand(operand, resulttype, result);
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["FIND"] = [SocialCalc.Formula.StringFunctions, -2, "find", "", "text"];
+SocialCalc.Formula.FunctionList["LEFT"] = [SocialCalc.Formula.StringFunctions, -2, "tc", "", "text"];
+SocialCalc.Formula.FunctionList["LEN"] = [SocialCalc.Formula.StringFunctions, 1, "txt", "", "text"];
+SocialCalc.Formula.FunctionList["LOWER"] = [SocialCalc.Formula.StringFunctions, 1, "txt", "", "text"];
+SocialCalc.Formula.FunctionList["MID"] = [SocialCalc.Formula.StringFunctions, 3, "mid", "", "text"];
+SocialCalc.Formula.FunctionList["PROPER"] = [SocialCalc.Formula.StringFunctions, 1, "v", "", "text"];
+SocialCalc.Formula.FunctionList["REPLACE"] = [SocialCalc.Formula.StringFunctions, 4, "replace", "", "text"];
+SocialCalc.Formula.FunctionList["REPT"] = [SocialCalc.Formula.StringFunctions, 2, "tc", "", "text"];
+SocialCalc.Formula.FunctionList["RIGHT"] = [SocialCalc.Formula.StringFunctions, -1, "tc", "", "text"];
+SocialCalc.Formula.FunctionList["SUBSTITUTE"] = [SocialCalc.Formula.StringFunctions, -3, "subs", "", "text"];
+SocialCalc.Formula.FunctionList["TRIM"] = [SocialCalc.Formula.StringFunctions, 1, "v", "", "text"];
+SocialCalc.Formula.FunctionList["UPPER"] = [SocialCalc.Formula.StringFunctions, 1, "v", "", "text"];
+
+/*
+#
+# is_functions:
+#
+# ISBLANK(value)
+# ISERR(value)
+# ISERROR(value)
+# ISLOGICAL(value)
+# ISNA(value)
+# ISNONTEXT(value)
+# ISNUMBER(value)
+# ISTEXT(value)
+#
+*/
+
+SocialCalc.Formula.IsFunctions = function(fname, operand, foperand, sheet) {
+
+ var scf = SocialCalc.Formula;
+ var result = 0;
+ var resulttype = "nl";
+
+ var value = scf.OperandValueAndType(sheet, foperand);
+ var t = value.type.charAt(0);
+
+ switch (fname) {
+
+ case "ISBLANK":
+ result = value.type == "b" ? 1 : 0;
+ break;
+
+ case "ISERR":
+ result = t == "e" ? (value.type == "e#N/A" ? 0 : 1) : 0;
+ break;
+
+ case "ISERROR":
+ result = t == "e" ? 1 : 0;
+ break;
+
+ case "ISLOGICAL":
+ result = value.type == "nl" ? 1 : 0;
+ break;
+
+ case "ISNA":
+ result = value.type == "e#N/A" ? 1 : 0;
+ break;
+
+ case "ISNONTEXT":
+ result = t == "t" ? 0 : 1;
+ break;
+
+ case "ISNUMBER":
+ result = t == "n" ? 1 : 0;
+ break;
+
+ case "ISTEXT":
+ result = t == "t" ? 1 : 0;
+ break;
+ }
+
+ scf.PushOperand(operand, resulttype, result);
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["ISBLANK"] = [SocialCalc.Formula.IsFunctions, 1, "v", "", "test"];
+SocialCalc.Formula.FunctionList["ISERR"] = [SocialCalc.Formula.IsFunctions, 1, "v", "", "test"];
+SocialCalc.Formula.FunctionList["ISERROR"] = [SocialCalc.Formula.IsFunctions, 1, "v", "", "test"];
+SocialCalc.Formula.FunctionList["ISLOGICAL"] = [SocialCalc.Formula.IsFunctions, 1, "v", "", "test"];
+SocialCalc.Formula.FunctionList["ISNA"] = [SocialCalc.Formula.IsFunctions, 1, "v", "", "test"];
+SocialCalc.Formula.FunctionList["ISNONTEXT"] = [SocialCalc.Formula.IsFunctions, 1, "v", "", "test"];
+SocialCalc.Formula.FunctionList["ISNUMBER"] = [SocialCalc.Formula.IsFunctions, 1, "v", "", "test"];
+SocialCalc.Formula.FunctionList["ISTEXT"] = [SocialCalc.Formula.IsFunctions, 1, "v", "", "test"];
+
+/*
+#
+# ntv_functions:
+#
+# N(value)
+# T(value)
+# VALUE(value)
+#
+*/
+
+SocialCalc.Formula.NTVFunctions = function(fname, operand, foperand, sheet) {
+
+ var scf = SocialCalc.Formula;
+ var result = 0;
+ var resulttype = "e#VALUE!";
+
+ var value = scf.OperandValueAndType(sheet, foperand);
+ var t = value.type.charAt(0);
+
+ switch (fname) {
+
+ case "N":
+ result = t == "n" ? value.value-0 : 0;
+ resulttype = "n";
+ break;
+
+ case "T":
+ result = t == "t" ? value.value+"" : "";
+ resulttype = "t";
+ break;
+
+ case "VALUE":
+ if (t == "n" || t == "b") {
+ result = value.value || 0;
+ resulttype = "n";
+ }
+ else if (t == "t") {
+ value = SocialCalc.DetermineValueType(value.value);
+ if (value.type.charAt(0) != "n") {
+ result = 0;
+ resulttype = "e#VALUE!";
+ }
+ else {
+ result = value.value-0;
+ resulttype = "n";
+ }
+ }
+ break;
+ }
+
+ if (t == "e") { // error trumps
+ resulttype = value.type;
+ }
+
+ scf.PushOperand(operand, resulttype, result);
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["N"] = [SocialCalc.Formula.NTVFunctions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["T"] = [SocialCalc.Formula.NTVFunctions, 1, "v", "", "text"];
+SocialCalc.Formula.FunctionList["VALUE"] = [SocialCalc.Formula.NTVFunctions, 1, "v", "", "text"];
+
+/*
+#
+# ABS(value)
+# ACOS(value)
+# ASIN(value)
+# ATAN(value)
+# COS(value)
+# DEGREES(value)
+# EVEN(value)
+# EXP(value)
+# FACT(value)
+# INT(value)
+# LN(value)
+# LOG10(value)
+# ODD(value)
+# RADIANS(value)
+# SIN(value)
+# SQRT(value)
+# TAN(value)
+#
+*/
+
+SocialCalc.Formula.Math1Functions = function(fname, operand, foperand, sheet) {
+
+ var v1, value, f;
+ var result = {};
+
+ var scf = SocialCalc.Formula;
+
+ v1 = scf.OperandAsNumber(sheet, foperand);
+ value = v1.value;
+ result.type = scf.LookupResultType(v1.type, v1.type, scf.TypeLookupTable.oneargnumeric);
+
+ if (result.type == "n") {
+ switch (fname) {
+ case "ABS":
+ value = Math.abs(value);
+ break;
+
+ case "ACOS":
+ if (value >= -1 && value <= 1) {
+ value = Math.acos(value);
+ }
+ else {
+ result.type = "e#NUM!";
+ }
+ break;
+
+ case "ASIN":
+ if (value >= -1 && value <= 1) {
+ value = Math.asin(value);
+ }
+ else {
+ result.type = "e#NUM!";
+ }
+ break;
+
+ case "ATAN":
+ value = Math.atan(value);
+ break;
+
+ case "COS":
+ value = Math.cos(value);
+ break;
+
+ case "DEGREES":
+ value = value * 180/Math.PI;
+ break;
+
+ case "EVEN":
+ value = value < 0 ? -value : value;
+ if (value != Math.floor(value)) {
+ value = Math.floor(value + 1) + (Math.floor(value + 1) % 2);
+ }
+ else { // integer
+ value = value + (value % 2);
+ }
+ if (v1.value < 0) value = -value;
+ break;
+
+ case "EXP":
+ value = Math.exp(value);
+ break;
+
+ case "FACT":
+ f = 1;
+ value = Math.floor(value);
+ for (;value>0;value--) {
+ f *= value;
+ }
+ value = f;
+ break;
+
+ case "INT":
+ value = Math.floor(value); // spreadsheet INT is floor(), not int()
+ break;
+
+ case "LN":
+ if (value <= 0) {
+ result.type = "e#NUM!";
+ result.error = SocialCalc.Constants.s_sheetfunclnarg;
+ }
+ value = Math.log(value);
+ break;
+
+ case "LOG10":
+ if (value <= 0) {
+ result.type = "e#NUM!";
+ result.error = SocialCalc.Constants.s_sheetfunclog10arg;
+ }
+ value = Math.log(value)/Math.log(10);
+ break;
+
+ case "ODD":
+ value = value < 0 ? -value : value;
+ if (value != Math.floor(value)) {
+ value = Math.floor(value + 1) + (1 - (Math.floor(value + 1) % 2));
+ }
+ else { // integer
+ value = value + (1 - (value % 2));
+ }
+ if (v1.value < 0) value = -value;
+ break;
+
+ case "RADIANS":
+ value = value * Math.PI/180;
+ break;
+
+ case "SIN":
+ value = Math.sin(value);
+ break;
+
+ case "SQRT":
+ if (value >= 0) {
+ value = Math.sqrt(value);
+ }
+ else {
+ result.type = "e#NUM!";
+ }
+ break;
+
+ case "TAN":
+ if (Math.cos(value) != 0) {
+ value = Math.tan(value);
+ }
+ else {
+ result.type = "e#NUM!";
+ }
+ break;
+ }
+ }
+
+ result.value = value;
+ operand.push(result);
+
+ return null;
+
+ }
+
+// Add to function list
+SocialCalc.Formula.FunctionList["ABS"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["ACOS"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["ASIN"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["ATAN"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["COS"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["DEGREES"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["EVEN"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["EXP"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["FACT"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["INT"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["LN"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["LOG10"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["ODD"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["RADIANS"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["SIN"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["SQRT"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+SocialCalc.Formula.FunctionList["TAN"] = [SocialCalc.Formula.Math1Functions, 1, "v", "", "math"];
+
+
+/*
+#
+# ATAN2(x, y)
+# MOD(a, b)
+# POWER(a, b)
+# TRUNC(value, precision)
+#
+*/
+
+SocialCalc.Formula.Math2Functions = function(fname, operand, foperand, sheet) {
+
+ var xval, yval, value, quotient, decimalscale, i;
+ var result = {};
+
+ var scf = SocialCalc.Formula;
+
+ xval = scf.OperandAsNumber(sheet, foperand);
+ yval = scf.OperandAsNumber(sheet, foperand);
+ value = 0;
+ result.type = scf.LookupResultType(xval.type, yval.type, scf.TypeLookupTable.twoargnumeric);
+
+ if (result.type == "n") {
+ switch (fname) {
+ case "ATAN2":
+ if (xval.value == 0 && yval.value == 0) {
+ result.type = "e#DIV/0!";
+ }
+ else {
+ result.value = Math.atan2(yval.value, xval.value);
+ }
+ break;
+
+ case "POWER":
+ result.value = Math.pow(xval.value, yval.value);
+ if (isNaN(result.value)) {
+ result.value = 0;
+ result.type = "e#NUM!";
+ }
+ break;
+
+ case "MOD": // en.wikipedia.org/wiki/Modulo_operation, etc.
+ if (yval.value == 0) {
+ result.type = "e#DIV/0!";
+ }
+ else {
+ quotient = xval.value/yval.value;
+ quotient = Math.floor(quotient);
+ result.value = xval.value - (quotient * yval.value);
+ }
+ break;
+
+ case "TRUNC":
+ decimalscale = 1; // cut down to required number of decimal digits
+ if (yval.value >= 0) {
+ yval.value = Math.floor(yval.value);
+ for (i=0; i<yval.value; i++) {
+ decimalscale *= 10;
+ }
+ result.value = Math.floor(Math.abs(xval.value) * decimalscale) / decimalscale;
+ }
+ else if (yval.value < 0) {
+ yval.value = Math.floor(-yval.value);
+ for (i=0; i<yval.value; i++) {
+ decimalscale *= 10;
+ }
+ result.value = Math.floor(Math.abs(xval.value) / decimalscale) * decimalscale;
+ }
+ if (xval.value < 0) {
+ result.value = -result.value;
+ }
+ }
+ }
+
+ operand.push(result);
+
+ return null;
+
+ }
+
+// Add to function list
+SocialCalc.Formula.FunctionList["ATAN2"] = [SocialCalc.Formula.Math2Functions, 2, "xy", "", "math"];
+SocialCalc.Formula.FunctionList["MOD"] = [SocialCalc.Formula.Math2Functions, 2, "", "", "math"];
+SocialCalc.Formula.FunctionList["POWER"] = [SocialCalc.Formula.Math2Functions, 2, "", "", "math"];
+SocialCalc.Formula.FunctionList["TRUNC"] = [SocialCalc.Formula.Math2Functions, 2, "valpre", "", "math"];
+
+/*
+#
+# LOG(value,[base])
+#
+*/
+
+SocialCalc.Formula.LogFunction = function(fname, operand, foperand, sheet) {
+
+ var value, value2;
+ var result = {};
+
+ var scf = SocialCalc.Formula;
+
+ result.value = 0;
+
+ value = scf.OperandAsNumber(sheet, foperand);
+ result.type = scf.LookupResultType(value.type, value.type, scf.TypeLookupTable.oneargnumeric);
+ if (foperand.length == 1) {
+ value2 = scf.OperandAsNumber(sheet, foperand);
+ if (value2.type.charAt(0) != "n" || value2.value <= 0) {
+ scf.FunctionSpecificError(fname, operand, "e#NUM!", SocialCalc.Constants.s_sheetfunclogsecondarg);
+ return 0;
+ }
+ }
+ else if (foperand.length != 0) {
+ scf.FunctionArgsError(fname, operand);
+ return 0;
+ }
+ else {
+ value2 = {value: Math.E, type: "n"};
+ }
+
+ if (result.type == "n") {
+ if (value.value <= 0) {
+ scf.FunctionSpecificError(fname, operand, "e#NUM!", SocialCalc.Constants.s_sheetfunclogfirstarg);
+ return 0;
+ }
+ result.value = Math.log(value.value)/Math.log(value2.value);
+ }
+
+ operand.push(result);
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["LOG"] = [SocialCalc.Formula.LogFunction, -1, "log", "", "math"];
+
+
+/*
+#
+# ROUND(value,[precision])
+#
+*/
+
+SocialCalc.Formula.RoundFunction = function(fname, operand, foperand, sheet) {
+
+ var value2, decimalscale, scaledvalue, i;
+
+ var scf = SocialCalc.Formula;
+ var result = 0;
+ var resulttype = "e#VALUE!";
+
+ var value = scf.OperandValueAndType(sheet, foperand);
+ var resulttype = scf.LookupResultType(value.type, value.type, scf.TypeLookupTable.oneargnumeric);
+
+ if (foperand.length == 1) {
+ value2 = scf.OperandValueAndType(sheet, foperand);
+ if (value2.type.charAt(0) != "n") {
+ scf.FunctionSpecificError(fname, operand, "e#NUM!", SocialCalc.Constants.s_sheetfuncroundsecondarg);
+ return 0;
+ }
+ }
+ else if (foperand.length != 0) {
+ scf.FunctionArgsError(fname, operand);
+ return 0;
+ }
+ else {
+ value2 = {value: 0, type: "n"}; // if no second arg, assume 0 for simple round
+ }
+
+ if (resulttype == "n") {
+ value2.value = value2.value-0;
+ if (value2.value == 0) {
+ result = Math.round(value.value);
+ }
+ else if (value2.value > 0) {
+ decimalscale = 1; // cut down to required number of decimal digits
+ value2.value = Math.floor(value2.value);
+ for (i=0; i<value2.value; i++) {
+ decimalscale *= 10;
+ }
+ scaledvalue = Math.round(value.value * decimalscale);
+ result = scaledvalue / decimalscale;
+ }
+ else if (value2.value < 0) {
+ decimalscale = 1; // cut down to required number of decimal digits
+ value2.value = Math.floor(-value2.value);
+ for (i=0; i<value2.value; i++) {
+ decimalscale *= 10;
+ }
+ scaledvalue = Math.round(value.value / decimalscale);
+ result = scaledvalue * decimalscale;
+ }
+ }
+
+ scf.PushOperand(operand, resulttype, result);
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["ROUND"] = [SocialCalc.Formula.RoundFunction, -1, "vp", "", "math"];
+
+/*
+#
+# AND(v1,c1:c2,...)
+# OR(v1,c1:c2,...)
+#
+*/
+
+SocialCalc.Formula.AndOrFunctions = function(fname, operand, foperand, sheet) {
+
+ var value1, result;
+
+ var scf = SocialCalc.Formula;
+ var resulttype = "";
+
+ if (fname == "AND") {
+ result = 1;
+ }
+ else if (fname == "OR") {
+ result = 0;
+ }
+
+ while (foperand.length) {
+ value1 = scf.OperandValueAndType(sheet, foperand);
+ if (value1.type.charAt(0) == "n") {
+ value1.value = value1.value-0;
+ if (fname == "AND") {
+ result = value1.value != 0 ? result : 0;
+ }
+ else if (fname == "OR") {
+ result = value1.value != 0 ? 1 : result;
+ }
+ resulttype = scf.LookupResultType(value1.type, resulttype || "nl", scf.TypeLookupTable.propagateerror);
+ }
+ else if (value1.type.charAt(0) == "e" && resulttype.charAt(0) != "e") {
+ resulttype = value1.type;
+ }
+ }
+ if (resulttype.length < 1) {
+ resulttype = "e#VALUE!";
+ result = 0;
+ }
+
+ scf.PushOperand(operand, resulttype, result);
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["AND"] = [SocialCalc.Formula.AndOrFunctions, -1, "vn", "", "test"];
+SocialCalc.Formula.FunctionList["OR"] = [SocialCalc.Formula.AndOrFunctions, -1, "vn", "", "test"];
+
+/*
+#
+# NOT(value)
+#
+*/
+
+SocialCalc.Formula.NotFunction = function(fname, operand, foperand, sheet) {
+
+ var result = 0;
+ var scf = SocialCalc.Formula;
+ var value = scf.OperandValueAndType(sheet, foperand);
+ var resulttype = scf.LookupResultType(value.type, value.type, scf.TypeLookupTable.propagateerror);
+
+ if (value.type.charAt(0) == "n" || value.type == "b") {
+ result = value.value-0 != 0 ? 0 : 1; // do the "not" operation
+ resulttype = "nl";
+ }
+ else if (value.type.charAt(0) == "t") {
+ resulttype = "e#VALUE!";
+ }
+
+ scf.PushOperand(operand, resulttype, result);
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["NOT"] = [SocialCalc.Formula.NotFunction, 1, "v", "", "test"];
+
+/*
+#
+# CHOOSE(index,value1,value2,...)
+#
+*/
+
+SocialCalc.Formula.ChooseFunction = function(fname, operand, foperand, sheet) {
+
+ var resulttype, count, value1;
+ var result = 0;
+ var scf = SocialCalc.Formula;
+
+ var cindex = scf.OperandAsNumber(sheet, foperand);
+
+ if (cindex.type.charAt(0) != "n") {
+ cindex.value = 0;
+ }
+ cindex.value = Math.floor(cindex.value);
+
+ count = 0;
+ while (foperand.length) {
+ value1 = scf.TopOfStackValueAndType(sheet, foperand);
+ count += 1;
+ if (cindex.value == count) {
+ result = value1.value;
+ resulttype = value1.type;
+ break;
+ }
+ }
+ if (resulttype) { // found something
+ scf.PushOperand(operand, resulttype, result);
+ }
+ else {
+ scf.PushOperand(operand, "e#VALUE!", 0);
+ }
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["CHOOSE"] = [SocialCalc.Formula.ChooseFunction, -2, "choose", "", "lookup"];
+
+/*
+#
+# COLUMNS(c1:c2)
+# ROWS(c1:c2)
+#
+*/
+
+SocialCalc.Formula.ColumnsRowsFunctions = function(fname, operand, foperand, sheet) {
+
+ var resulttype, rangeinfo;
+ var result = 0;
+ var scf = SocialCalc.Formula;
+
+ var value1 = scf.TopOfStackValueAndType(sheet, foperand);
+
+ if (value1.type == "coord") {
+ result = 1;
+ resulttype = "n";
+ }
+
+ else if (value1.type == "range") {
+ rangeinfo = scf.DecodeRangeParts(sheet, value1.value);
+ if (fname == "COLUMNS") {
+ result = rangeinfo.ncols;
+ }
+ else if (fname == "ROWS") {
+ result = rangeinfo.nrows;
+ }
+ resulttype = "n";
+ }
+ else {
+ result = 0;
+ resulttype = "e#VALUE!";
+ }
+
+ scf.PushOperand(operand, resulttype, result);
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["COLUMNS"] = [SocialCalc.Formula.ColumnsRowsFunctions, 1, "range", "", "lookup"];
+SocialCalc.Formula.FunctionList["ROWS"] = [SocialCalc.Formula.ColumnsRowsFunctions, 1, "range", "", "lookup"];
+
+
+/*
+#
+# FALSE()
+# NA()
+# NOW()
+# PI()
+# TODAY()
+# TRUE()
+#
+*/
+
+SocialCalc.Formula.ZeroArgFunctions = function(fname, operand, foperand, sheet) {
+
+ var startval, tzoffset, start_1_1_1970, seconds_in_a_day, nowdays;
+ var result = {value: 0};
+
+ switch (fname) {
+ case "FALSE":
+ result.type = "nl";
+ result.value = 0;
+ break;
+
+ case "NA":
+ result.type = "e#N/A";
+ break;
+
+ case "NOW":
+ startval = new Date();
+ tzoffset = startval.getTimezoneOffset();
+ startval = startval.getTime() / 1000; // convert to seconds
+ start_1_1_1970 = 25569; // Day number of 1/1/1970 starting with 1/1/1900 as 1
+ seconds_in_a_day = 24 * 60 * 60;
+ nowdays = start_1_1_1970 + startval / seconds_in_a_day - tzoffset/(24*60);
+ result.value = nowdays;
+ result.type = "ndt";
+ SocialCalc.Formula.FreshnessInfo.volatile.NOW = true; // remember
+ break;
+
+ case "PI":
+ result.type = "n";
+ result.value = Math.PI;
+ break;
+
+ case "TODAY":
+ startval = new Date();
+ tzoffset = startval.getTimezoneOffset();
+ startval = startval.getTime() / 1000; // convert to seconds
+ start_1_1_1970 = 25569; // Day number of 1/1/1970 starting with 1/1/1900 as 1
+ seconds_in_a_day = 24 * 60 * 60;
+ nowdays = start_1_1_1970 + startval / seconds_in_a_day - tzoffset/(24*60);
+ result.value = Math.floor(nowdays);
+ result.type = "nd";
+ SocialCalc.Formula.FreshnessInfo.volatile.TODAY = true; // remember
+ break;
+
+ case "TRUE":
+ result.type = "nl";
+ result.value = 1;
+ break;
+
+ }
+
+ operand.push(result);
+
+ return null;
+
+}
+
+// Add to function list
+SocialCalc.Formula.FunctionList["FALSE"] = [SocialCalc.Formula.ZeroArgFunctions, 0, "", "", "test"];
+SocialCalc.Formula.FunctionList["NA"] = [SocialCalc.Formula.ZeroArgFunctions, 0, "", "", "test"];
+SocialCalc.Formula.FunctionList["NOW"] = [SocialCalc.Formula.ZeroArgFunctions, 0, "", "", "datetime"];
+SocialCalc.Formula.FunctionList["PI"] = [SocialCalc.Formula.ZeroArgFunctions, 0, "", "", "math"];
+SocialCalc.Formula.FunctionList["TODAY"] = [SocialCalc.Formula.ZeroArgFunctions, 0, "", "", "datetime"];
+SocialCalc.Formula.FunctionList["TRUE"] = [SocialCalc.Formula.ZeroArgFunctions, 0, "", "", "test"];
+
+//
+// * * * * * FINANCIAL FUNCTIONS * * * * *
+//
+
+/*
+#
+# DDB(cost,salvage,lifetime,period,[method])
+#
+# Depreciation, method defaults to 2 for double-declining balance
+# See: http://en.wikipedia.org/wiki/Depreciation
+#
+*/
+
+SocialCalc.Formula.DDBFunction = function(fname, operand, foperand, sheet) {
+
+ var method, depreciation, accumulateddepreciation, i;
+ var scf = SocialCalc.Formula;
+
+ var cost = scf.OperandAsNumber(sheet, foperand);
+ var salvage = scf.OperandAsNumber(sheet, foperand);
+ var lifetime = scf.OperandAsNumber(sheet, foperand);
+ var period = scf.OperandAsNumber(sheet, foperand);
+
+ if (scf.CheckForErrorValue(operand, cost)) return;
+ if (scf.CheckForErrorValue(operand, salvage)) return;
+ if (scf.CheckForErrorValue(operand, lifetime)) return;
+ if (scf.CheckForErrorValue(operand, period)) return;
+
+ if (lifetime.value < 1) {
+ scf.FunctionSpecificError(fname, operand, "e#NUM!", SocialCalc.Constants.s_sheetfuncddblife);
+ return 0;
+ }
+
+ method = {value: 2, type: "n"};
+ if (foperand.length > 0 ) {
+ method = scf.OperandAsNumber(sheet, foperand);
+ }
+ if (foperand.length != 0) {
+ scf.FunctionArgsError(fname, operand);
+ return 0;
+ }
+ if (scf.CheckForErrorValue(operand, method)) return;
+
+ depreciation = 0; // calculated for each period
+ accumulateddepreciation = 0; // accumulated by adding each period's
+
+ for (i=1; i<=period.value-0 && i<=lifetime.value; i++) { // calculate for each period based on net from previous
+ depreciation = (cost.value - accumulateddepreciation) * (method.value / lifetime.value);
+ if (cost.value - accumulateddepreciation - depreciation < salvage.value) { // don't go lower than salvage value
+ depreciation = cost.value - accumulateddepreciation - salvage.value;
+ }
+ accumulateddepreciation += depreciation;
+ }
+
+ scf.PushOperand(operand, 'n$', depreciation);
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["DDB"] = [SocialCalc.Formula.DDBFunction, -4, "ddb", "", "financial"];
+
+/*
+#
+# SLN(cost,salvage,lifetime)
+#
+# Depreciation for each period by straight-line method
+# See: http://en.wikipedia.org/wiki/Depreciation
+#
+*/
+
+SocialCalc.Formula.SLNFunction = function(fname, operand, foperand, sheet) {
+
+ var depreciation;
+ var scf = SocialCalc.Formula;
+
+ var cost = scf.OperandAsNumber(sheet, foperand);
+ var salvage = scf.OperandAsNumber(sheet, foperand);
+ var lifetime = scf.OperandAsNumber(sheet, foperand);
+
+ if (scf.CheckForErrorValue(operand, cost)) return;
+ if (scf.CheckForErrorValue(operand, salvage)) return;
+ if (scf.CheckForErrorValue(operand, lifetime)) return;
+
+ if (lifetime.value < 1) {
+ scf.FunctionSpecificError(fname, operand, "e#NUM!", SocialCalc.Constants.s_sheetfuncslnlife);
+ return 0;
+ }
+
+ depreciation = (cost.value - salvage.value) / lifetime.value;
+
+ scf.PushOperand(operand, 'n$', depreciation);
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["SLN"] = [SocialCalc.Formula.SLNFunction, 3, "csl", "", "financial"];
+
+/*
+#
+# SYD(cost,salvage,lifetime,period)
+#
+# Depreciation by Sum of Year's Digits method
+#
+*/
+
+SocialCalc.Formula.SYDFunction = function(fname, operand, foperand, sheet) {
+
+ var depreciation, sumperiods;
+ var scf = SocialCalc.Formula;
+
+ var cost = scf.OperandAsNumber(sheet, foperand);
+ var salvage = scf.OperandAsNumber(sheet, foperand);
+ var lifetime = scf.OperandAsNumber(sheet, foperand);
+ var period = scf.OperandAsNumber(sheet, foperand);
+
+ if (scf.CheckForErrorValue(operand, cost)) return;
+ if (scf.CheckForErrorValue(operand, salvage)) return;
+ if (scf.CheckForErrorValue(operand, lifetime)) return;
+ if (scf.CheckForErrorValue(operand, period)) return;
+
+ if (lifetime.value < 1 || period.value <= 0) {
+ scf.PushOperand(operand, "e#NUM!", 0);
+ return 0;
+ }
+
+ sumperiods = ((lifetime.value + 1) * lifetime.value)/2; // add up 1 through lifetime
+ depreciation = (cost.value - salvage.value) * (lifetime.value - period.value + 1) / sumperiods; // calc depreciation
+
+ scf.PushOperand(operand, 'n$', depreciation);
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["SYD"] = [SocialCalc.Formula.SYDFunction, 4, "cslp", "", "financial"];
+
+/*
+#
+# FV(rate, n, payment, [pv, [paytype]])
+# NPER(rate, payment, pv, [fv, [paytype]])
+# PMT(rate, n, pv, [fv, [paytype]])
+# PV(rate, n, payment, [fv, [paytype]])
+# RATE(n, payment, pv, [fv, [paytype, [guess]]])
+#
+# Following the Open Document Format formula specification:
+#
+# PV = - Fv - (Payment * Nper) [if rate equals 0]
+# Pv*(1+Rate)^Nper + Payment * (1 + Rate*PaymentType) * ( (1+Rate)^nper -1)/Rate + Fv = 0
+#
+# For each function, the formulas are solved for the appropriate value (transformed using
+# basic algebra).
+#
+*/
+
+SocialCalc.Formula.InterestFunctions = function(fname, operand, foperand, sheet) {
+
+ var resulttype, result, dval, eval, fval;
+ var pv, fv, rate, n, payment, paytype, guess, part1, part2, part3, part4, part5;
+ var olddelta, maxloop, tries, deltaepsilon, rate, oldrate, m;
+
+ var scf = SocialCalc.Formula;
+
+ var aval = scf.OperandAsNumber(sheet, foperand);
+ var bval = scf.OperandAsNumber(sheet, foperand);
+ var cval = scf.OperandAsNumber(sheet, foperand);
+
+ resulttype = scf.LookupResultType(aval.type, bval.type, scf.TypeLookupTable.twoargnumeric);
+ resulttype = scf.LookupResultType(resulttype, cval.type, scf.TypeLookupTable.twoargnumeric);
+ if (foperand.length) { // optional arguments
+ dval = scf.OperandAsNumber(sheet, foperand);
+ resulttype = scf.LookupResultType(resulttype, dval.type, scf.TypeLookupTable.twoargnumeric);
+ if (foperand.length) { // optional arguments
+ eval = scf.OperandAsNumber(sheet, foperand);
+ resulttype = scf.LookupResultType(resulttype, eval.type, scf.TypeLookupTable.twoargnumeric);
+ if (foperand.length) { // optional arguments
+ if (fname != "RATE") { // only rate has 6 possible args
+ scf.FunctionArgsError(fname, operand);
+ return 0;
+ }
+ fval = scf.OperandAsNumber(sheet, foperand);
+ resulttype = scf.LookupResultType(resulttype, fval.type, scf.TypeLookupTable.twoargnumeric);
+ }
+ }
+ }
+
+ if (resulttype == "n") {
+ switch (fname) {
+ case "FV": // FV(rate, n, payment, [pv, [paytype]])
+ rate = aval.value;
+ n = bval.value;
+ payment = cval.value;
+ pv = dval!=null ? dval.value : 0; // get value if present, or use default
+ paytype = eval!=null ? (eval.value ? 1 : 0) : 0;
+ if (rate == 0) { // simple calculation if no interest
+ fv = -pv - (payment * n);
+ }
+ else {
+ fv = -(pv*Math.pow(1+rate,n) + payment * (1 + rate*paytype) * ( Math.pow(1+rate,n) -1)/rate);
+ }
+ result = fv;
+ resulttype = 'n$';
+ break;
+
+ case "NPER": // NPER(rate, payment, pv, [fv, [paytype]])
+ rate = aval.value;
+ payment = bval.value;
+ pv = cval.value;
+ fv = dval!=null ? dval.value : 0;
+ paytype = eval!=null ? (eval.value ? 1 : 0) : 0;
+ if (rate == 0) { // simple calculation if no interest
+ if (payment == 0) {
+ scf.PushOperand(operand, "e#NUM!", 0);
+ return;
+ }
+ n = (pv + fv)/(-payment);
+ }
+ else {
+ part1 = payment * (1 + rate * paytype) / rate;
+ part2 = pv + part1;
+ if (part2 == 0 || rate <= -1) {
+ scf.PushOperand(operand, "e#NUM!", 0);
+ return;
+ }
+ part3 = (part1 - fv) / part2;
+ if (part3 <= 0) {
+ scf.PushOperand(operand, "e#NUM!", 0);
+ return;
+ }
+ part4 = Math.log(part3);
+ part5 = Math.log(1 + rate); // rate > -1
+ n = part4/part5;
+ }
+ result = n;
+ resulttype = 'n';
+ break;
+
+ case "PMT": // PMT(rate, n, pv, [fv, [paytype]])
+ rate = aval.value;
+ n = bval.value;
+ pv = cval.value;
+ fv = dval!=null ? dval.value : 0;
+ paytype = eval!=null ? (eval.value ? 1 : 0) : 0;
+ if (n == 0) {
+ scf.PushOperand(operand, "e#NUM!", 0);
+ return;
+ }
+ else if (rate == 0) { // simple calculation if no interest
+ payment = (fv - pv)/n;
+ }
+ else {
+ payment = (0 - fv - pv*Math.pow(1+rate,n))/((1 + rate*paytype) * ( Math.pow(1+rate,n) -1)/rate);
+ }
+ result = payment;
+ resulttype = 'n$';
+ break;
+
+ case "PV": // PV(rate, n, payment, [fv, [paytype]])
+ rate = aval.value;
+ n = bval.value;
+ payment = cval.value;
+ fv = dval!=null ? dval.value : 0;
+ paytype = eval!=null ? (eval.value ? 1 : 0) : 0;
+ if (rate == -1) {
+ scf.PushOperand(operand, "e#DIV/0!", 0);
+ return;
+ }
+ else if (rate == 0) { // simple calculation if no interest
+ pv = -fv - (payment * n);
+ }
+ else {
+ pv = (-fv - payment * (1 + rate*paytype) * ( Math.pow(1+rate,n) -1)/rate)/(Math.pow(1+rate,n));
+ }
+ result = pv;
+ resulttype = 'n$';
+ break;
+
+ case "RATE": // RATE(n, payment, pv, [fv, [paytype, [guess]]])
+ n = aval.value;
+ payment = bval.value;
+ pv = cval.value;
+ fv = dval!=null ? dval.value : 0;
+ paytype = eval!=null ? (eval.value ? 1 : 0) : 0;
+ guess = fval!=null ? fval.value : 0.1;
+
+ // rate is calculated by repeated approximations
+ // The deltas are used to calculate new guesses
+
+ maxloop = 100;
+ tries = 0;
+ delta = 1;
+ epsilon = 0.0000001; // this is close enough
+ rate = guess || 0.00000001; // zero is not allowed
+ while ((delta >= 0 ? delta : -delta) > epsilon && (rate != oldrate)) {
+ delta = fv + pv*Math.pow(1+rate,n) + payment * (1 + rate*paytype) * ( Math.pow(1+rate,n) -1)/rate;
+ if (olddelta!=null) {
+ m = (delta - olddelta)/(rate - oldrate) || .001; // get slope (not zero)
+ oldrate = rate;
+ rate = rate - delta / m; // look for zero crossing
+ olddelta = delta;
+ }
+ else { // first time - no old values
+ oldrate = rate;
+ rate = 1.1 * rate;
+ olddelta = delta;
+ }
+ tries++;
+ if (tries >= maxloop) { // didn't converge yet
+ scf.PushOperand(operand, "e#NUM!", 0);
+ return;
+ }
+ }
+ result = rate;
+ resulttype = 'n%';
+ break;
+ }
+ }
+
+ scf.PushOperand(operand, resulttype, result);
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["FV"] = [SocialCalc.Formula.InterestFunctions, -3, "fv", "", "financial"];
+SocialCalc.Formula.FunctionList["NPER"] = [SocialCalc.Formula.InterestFunctions, -3, "nper", "", "financial"];
+SocialCalc.Formula.FunctionList["PMT"] = [SocialCalc.Formula.InterestFunctions, -3, "pmt", "", "financial"];
+SocialCalc.Formula.FunctionList["PV"] = [SocialCalc.Formula.InterestFunctions, -3, "pv", "", "financial"];
+SocialCalc.Formula.FunctionList["RATE"] = [SocialCalc.Formula.InterestFunctions, -3, "rate", "", "financial"];
+
+/*
+#
+# NPV(rate,v1,v2,c1:c2,...)
+#
+*/
+
+SocialCalc.Formula.NPVFunction = function(fname, operand, foperand, sheet) {
+
+ var resulttypenpv, rate, sum, factor, value1;
+
+ var scf = SocialCalc.Formula;
+
+ var rate = scf.OperandAsNumber(sheet, foperand);
+ if (scf.CheckForErrorValue(operand, rate)) return;
+
+ sum = 0;
+ resulttypenpv = "n";
+ factor = 1;
+
+ while (foperand.length) {
+ value1 = scf.OperandValueAndType(sheet, foperand);
+ if (value1.type.charAt(0) == "n") {
+ factor *= (1 + rate.value);
+ if (factor == 0) {
+ scf.PushOperand(operand, "e#DIV/0!", 0);
+ return;
+ }
+ sum += value1.value / factor;
+ resulttypenpv = scf.LookupResultType(value1.type, resulttypenpv || value1.type, scf.TypeLookupTable.plus);
+ }
+ else if (value1.type.charAt(0) == "e" && resulttypenpv.charAt(0) != "e") {
+ resulttypenpv = value1.type;
+ break;
+ }
+ }
+
+ if (resulttypenpv.charAt(0) == "n") {
+ resulttypenpv = 'n$';
+ }
+
+ scf.PushOperand(operand, resulttypenpv, sum);
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["NPV"] = [SocialCalc.Formula.NPVFunction, -2, "npv", "", "financial"];
+
+/*
+#
+# IRR(c1:c2,[guess])
+#
+*/
+
+SocialCalc.Formula.IRRFunction = function(fname, operand, foperand, sheet) {
+
+ var value1, guess, oldsum, maxloop, tries, epsilon, rate, oldrate, m, sum, factor, i;
+ var rangeoperand = [];
+ var cashflows = [];
+
+ var scf = SocialCalc.Formula;
+
+ rangeoperand.push(foperand.pop()); // first operand is a range
+
+ while (rangeoperand.length) { // get values from range so we can do iterative approximations
+ value1 = scf.OperandValueAndType(sheet, rangeoperand);
+ if (value1.type.charAt(0) == "n") {
+ cashflows.push(value1.value);
+ }
+ else if (value1.type.charAt(0) == "e") {
+ scf.PushOperand(operand, "e#VALUE!", 0);
+ return;
+ }
+ }
+
+ if (!cashflows.length) {
+ scf.PushOperand(operand, "e#NUM!", 0);
+ return;
+ }
+
+ guess = {value: 0};
+
+ if (foperand.length) { // guess is provided
+ guess = scf.OperandAsNumber(sheet, foperand);
+ if (guess.type.charAt(0) != "n" && guess.type.charAt(0) != "b") {
+ scf.PushOperand(operand, "e#VALUE!", 0);
+ return;
+ }
+ if (foperand.length) { // should be no more args
+ scf.FunctionArgsError(fname, operand);
+ return;
+ }
+ }
+
+ guess.value = guess.value || 0.1;
+
+ // rate is calculated by repeated approximations
+ // The deltas are used to calculate new guesses
+
+ maxloop = 20;
+ tries = 0;
+ epsilon = 0.0000001; // this is close enough
+ rate = guess.value;
+ sum = 1;
+
+ while ((sum >= 0 ? sum : -sum) > epsilon && (rate != oldrate)) {
+ sum = 0;
+ factor = 1;
+ for (i=0; i<cashflows.length; i++) {
+ factor *= (1 + rate);
+ if (factor == 0) {
+ scf.PushOperand(operand, "e#DIV/0!", 0);
+ return;
+ }
+ sum += cashflows[i] / factor;
+ }
+
+ if (oldsum!=null) {
+ m = (sum - oldsum)/(rate - oldrate); // get slope
+ oldrate = rate;
+ rate = rate - sum / m; // look for zero crossing
+ oldsum = sum;
+ }
+ else { // first time - no old values
+ oldrate = rate;
+ rate = 1.1 * rate;
+ oldsum = sum;
+ }
+ tries++;
+ if (tries >= maxloop) { // didn't converge yet
+ scf.PushOperand(operand, "e#NUM!", 0);
+ return;
+ }
+ }
+
+ scf.PushOperand(operand, 'n%', rate);
+
+ return;
+
+ }
+
+SocialCalc.Formula.FunctionList["IRR"] = [SocialCalc.Formula.IRRFunction, -1, "irr", "", "financial"];
+
+//
+// SHEET CACHE
+//
+
+SocialCalc.Formula.SheetCache = {
+
+ // Sheet data: Attributes are each sheet in the cache with values of an object with:
+ //
+ // sheet: sheet-obj (or null, meaning not found)
+ // recalcstate: constants.asloaded = as loaded
+ // constants.recalcing = being recalced now
+ // constants.recalcdone = recalc done
+ // name: name of sheet (in case just have object and don't know name)
+ //
+
+ sheets: {},
+
+ // Waiting for loading:
+ // If sheet is not in cache, this is set to the sheetname being loaded
+ // so it can be tested in the recalc loop to start load and then wait until restarted.
+ // Reset to null before restarting.
+
+ waitingForLoading: null,
+
+ // Constants to use for setting sheets[*].recalcstate:
+
+ constants: {asloaded: 0, recalcing: 1, recalcdone: 2},
+
+ loadsheet: null // (deprecated - use SocialCalc.RecalcInfo.LoadSheet)
+
+ };
+
+//
+// othersheet = SocialCalc.Formula.FindInSheetCache(sheetname)
+//
+// Returns a SocialCalc.Sheet object corresponding to string sheetname
+// or null if the sheet is not available or in error.
+//
+// Each sheet is loaded only once and then stored in a cache.
+// Loading is handled elsewhere, e.g., in the recalc loop.
+//
+
+SocialCalc.Formula.FindInSheetCache = function(sheetname) {
+
+ var str;
+ var sfsc = SocialCalc.Formula.SheetCache;
+
+ var nsheetname = SocialCalc.Formula.NormalizeSheetName(sheetname); // normalize different versions
+
+ if (sfsc.sheets[nsheetname]) { // a sheet by that name is in the cache already
+ return sfsc.sheets[nsheetname].sheet; // return it
+ }
+
+ if (sfsc.waitingForLoading) { // waiting already - only queue up one
+ return null; // return not found
+ }
+
+ if (sfsc.loadsheet) { // Deprecated old format synchronous callback
+alert("Using SocialCalc.Formula.SheetCache.loadsheet - deprecated");
+ return SocialCalc.Formula.AddSheetToCache(nsheetname, sfsc.loadsheet(nsheetname));
+ }
+
+ sfsc.waitingForLoading = nsheetname; // let recalc loop know that we have a sheet to load
+
+ return null; // return not found
+
+ }
+
+//
+// newsheet = SocialCalc.Formula.AddSheetToCache(sheetname, str)
+//
+// Adds a new sheet to the sheet cache.
+// Returns the sheet object filled out with the str (a saved sheet).
+//
+
+SocialCalc.Formula.AddSheetToCache = function(sheetname, str) {
+
+ var newsheet = null;
+ var sfsc = SocialCalc.Formula.SheetCache;
+ var sfscc = sfsc.constants;
+ var newsheetname = SocialCalc.Formula.NormalizeSheetName(sheetname);
+
+ if (str) {
+ newsheet = new SocialCalc.Sheet();
+ newsheet.ParseSheetSave(str);
+ }
+
+ sfsc.sheets[newsheetname] = {sheet: newsheet, recalcstate: sfscc.asloaded, name: newsheetname};
+
+ SocialCalc.Formula.FreshnessInfo.sheets[newsheetname] = true;
+
+ return newsheet;
+
+ }
+
+//
+// nsheet = SocialCalc.Formula.NormalizeSheetName(sheetname)
+//
+
+SocialCalc.Formula.NormalizeSheetName = function(sheetname) {
+
+ if (SocialCalc.Callbacks.NormalizeSheetName) {
+ return SocialCalc.Callbacks.NormalizeSheetName(sheetname);
+ }
+ else {
+ return sheetname.toLowerCase();
+ }
+ }
+
+//
+// REMOTE FUNCTION INFO
+//
+
+SocialCalc.Formula.RemoteFunctionInfo = {
+
+ // Waiting for server:
+ // If waiting for an XHR response from the server, this is set to some non-blank status text
+ // so it can be tested in the recalc loop to start load and then wait until restarted.
+ // Reset to null before restarting.
+
+ waitingForServer: null
+
+ };
+
+//
+// FRESHNESS INFO
+//
+// This information is generated during recalc.
+// It may be used to help determine when the recalc data in a spreadsheet
+// may be out of date.
+// For example, it may be used to display a message like:
+// "Dependent on sheet 'FOO' which was updated more recently than this printout"
+
+SocialCalc.Formula.FreshnessInfo = {
+
+ // For each external sheet referenced successfully an attribute of that name with value true.
+
+ sheets: {},
+
+ // For each volatile function that is called an attribute of that name with value true.
+
+ volatile: {},
+
+ // Set to false when started and true when recalc completes
+
+ recalc_completed: false
+
+ };
+
+SocialCalc.Formula.FreshnessInfoReset = function() {
+
+ var scffi = SocialCalc.Formula.FreshnessInfo;
+
+ scffi.sheets = {};
+ scffi.volatile = {};
+ scffi.recalc_completed = false;
+
+ }
+
+//
+// MISC ROUTINES
+//
+
+//
+// result = SocialCalc.Formula.PlainCoord(coord)
+//
+// Returns: coord without any $'s
+//
+
+SocialCalc.Formula.PlainCoord = function(coord) {
+
+ if (coord.indexOf("$") == -1) return coord;
+
+ return coord.replace(/\$/g, ""); // remove any $'s
+
+ }
+
+//
+// result = SocialCalc.Formula.OrderRangeParts(coord1, coord2)
+//
+// Returns: {c1: col, r1: row, c2: col, r2 = row} with c1/r1 upper left
+//
+
+SocialCalc.Formula.OrderRangeParts = function(coord1, coord2) {
+
+ var cr1, cr2;
+ var result = {};
+
+ cr1 = SocialCalc.coordToCr(coord1);
+ cr2 = SocialCalc.coordToCr(coord2);
+ if (cr1.col > cr2.col) { result.c1 = cr2.col; result.c2 = cr1.col; }
+ else { result.c1 = cr1.col; result.c2 = cr2.col; }
+ if (cr1.row > cr2.row) { result.r1 = cr2.row; result.r2 = cr1.row; }
+ else { result.r1 = cr1.row; result.r2 = cr2.row; }
+
+ return result;
+
+ }
+
+//
+// cond = SocialCalc.Formula.TestCriteria(value, type, criteria)
+//
+// Determines whether a value/type meets the criteria.
+// A criteria can be a numeric value, text beginning with <, <=, =, >=, >, <>, text by itself is start of text to match.
+// Used by a variety of functions, including the "D" functions (DSUM, etc.).
+//
+// Returns true or false
+//
+
+SocialCalc.Formula.TestCriteria = function(value, type, criteria) {
+
+ var comparitor, basestring, basevalue, cond, testvalue;
+
+ if (criteria == null) { // undefined (e.g., error value) is always false
+ return false;
+ }
+
+ criteria = criteria + "";
+ comparitor = criteria.charAt(0); // look for comparitor
+ if (comparitor == "=" || comparitor == "<" || comparitor == ">") {
+ basestring = criteria.substring(1);
+ }
+ else {
+ comparitor = criteria.substring(0,2);
+ if (comparitor == "<=" || comparitor == "<>" || comparitor == ">=") {
+ basestring = criteria.substring(2);
+ }
+ else {
+ comparitor = "none";
+ basestring = criteria;
+ }
+ }
+
+ basevalue = SocialCalc.DetermineValueType(basestring); // get type of value being compared
+ if (!basevalue.type) { // no criteria base value given
+ if (comparitor == "none") { // blank criteria matches nothing
+ return false;
+ }
+ if (type.charAt(0) == "b") { // comparing to empty cell
+ if (comparitor == "=") { // empty equals empty
+ return true;
+ }
+ }
+ else {
+ if (comparitor == "<>") { // "something" does not equal empty
+ return true;
+ }
+ }
+ return false; // otherwise false
+ }
+
+ cond = false;
+
+ if (basevalue.type.charAt(0) == "n" && type.charAt(0) == "t") { // criteria is number, but value is text
+ testvalue = SocialCalc.DetermineValueType(value);
+ if (testvalue.type.charAt(0) == "n") { // could be number - make it one
+ value = testvalue.value;
+ type = testvalue.type;
+ }
+ }
+
+ if (type.charAt(0) == "n" && basevalue.type.charAt(0) == "n") { // compare two numbers
+ value = value - 0; // make sure numbers
+ basevalue.value = basevalue.value - 0;
+ switch (comparitor) {
+ case "<":
+ cond = value < basevalue.value;
+ break;
+
+ case "<=":
+ cond = value <= basevalue.value;
+ break;
+
+ case "=":
+ case "none":
+ cond = value == basevalue.value;
+ break;
+
+ case ">=":
+ cond = value >= basevalue.value;
+ break;
+
+ case ">":
+ cond = value > basevalue.value;
+ break;
+
+ case "<>":
+ cond = value != basevalue.value;
+ break;
+ }
+ }
+
+ else if (type.charAt(0) == "e") { // error on left
+ cond = false;
+ }
+
+ else if (basevalue.type.charAt(0) == "e") { // error on right
+ cond = false;
+ }
+
+ else { // text, maybe mixed with number or blank
+ if (type.charAt(0) == "n") {
+ value = SocialCalc.format_number_for_display(value, "n", "");
+ }
+ if (basevalue.type.charAt(0) == "n") {
+ return false; // if number and didn't match already, isn't a match
+ }
+
+ value = value ? value.toLowerCase() : "";
+ basevalue.value = basevalue.value ? basevalue.value.toLowerCase() : "";
+
+ switch (comparitor) {
+ case "<":
+ cond = value < basevalue.value;
+ break;
+
+ case "<=":
+ cond = value <= basevalue.value;
+ break;
+
+ case "=":
+ cond = value == basevalue.value;
+ break;
+
+ case "none":
+ cond = value.substring(0, basevalue.value.length) == basevalue.value;
+ break;
+
+ case ">=":
+ cond = value >= basevalue.value;
+ break;
+
+ case ">":
+ cond = value > basevalue.value;
+ break;
+
+ case "<>":
+ cond = value != basevalue.value;
+ break;
+ }
+ }
+
+ return cond;
+
+ }
+
diff --git a/web/images/sc-1x1.gif b/web/images/sc-1x1.gif
new file mode 100644
index 0000000..1d9a4f5
--- /dev/null
+++ b/web/images/sc-1x1.gif
Binary files differ
diff --git a/web/images/sc-aligncenter.gif b/web/images/sc-aligncenter.gif
new file mode 100644
index 0000000..81fae2a
--- /dev/null
+++ b/web/images/sc-aligncenter.gif
Binary files differ
diff --git a/web/images/sc-alignleft.gif b/web/images/sc-alignleft.gif
new file mode 100644
index 0000000..0f3fea7
--- /dev/null
+++ b/web/images/sc-alignleft.gif
Binary files differ
diff --git a/web/images/sc-alignright.gif b/web/images/sc-alignright.gif
new file mode 100644
index 0000000..c89e242
--- /dev/null
+++ b/web/images/sc-alignright.gif
Binary files differ
diff --git a/web/images/sc-bordersoff.gif b/web/images/sc-bordersoff.gif
new file mode 100644
index 0000000..ffad4a2
--- /dev/null
+++ b/web/images/sc-bordersoff.gif
Binary files differ
diff --git a/web/images/sc-borderson.gif b/web/images/sc-borderson.gif
new file mode 100644
index 0000000..0224acc
--- /dev/null
+++ b/web/images/sc-borderson.gif
Binary files differ
diff --git a/web/images/sc-chooserarrow.gif b/web/images/sc-chooserarrow.gif
new file mode 100644
index 0000000..b9010e2
--- /dev/null
+++ b/web/images/sc-chooserarrow.gif
Binary files differ
diff --git a/web/images/sc-commentbg.gif b/web/images/sc-commentbg.gif
new file mode 100644
index 0000000..0b5e17a
--- /dev/null
+++ b/web/images/sc-commentbg.gif
Binary files differ
diff --git a/web/images/sc-copy.gif b/web/images/sc-copy.gif
new file mode 100644
index 0000000..4ed54d0
--- /dev/null
+++ b/web/images/sc-copy.gif
Binary files differ
diff --git a/web/images/sc-cursorinsertleft.gif b/web/images/sc-cursorinsertleft.gif
new file mode 100644
index 0000000..03e9769
--- /dev/null
+++ b/web/images/sc-cursorinsertleft.gif
Binary files differ
diff --git a/web/images/sc-cursorinsertup.gif b/web/images/sc-cursorinsertup.gif
new file mode 100644
index 0000000..03e9769
--- /dev/null
+++ b/web/images/sc-cursorinsertup.gif
Binary files differ
diff --git a/web/images/sc-cut.gif b/web/images/sc-cut.gif
new file mode 100644
index 0000000..cb906cc
--- /dev/null
+++ b/web/images/sc-cut.gif
Binary files differ
diff --git a/web/images/sc-defaultcolor.gif b/web/images/sc-defaultcolor.gif
new file mode 100644
index 0000000..e9d69cd
--- /dev/null
+++ b/web/images/sc-defaultcolor.gif
Binary files differ
diff --git a/web/images/sc-delete.gif b/web/images/sc-delete.gif
new file mode 100644
index 0000000..b8d18a7
--- /dev/null
+++ b/web/images/sc-delete.gif
Binary files differ
diff --git a/web/images/sc-deletecol.gif b/web/images/sc-deletecol.gif
new file mode 100644
index 0000000..0242f70
--- /dev/null
+++ b/web/images/sc-deletecol.gif
Binary files differ
diff --git a/web/images/sc-deleterow.gif b/web/images/sc-deleterow.gif
new file mode 100644
index 0000000..0ff543e
--- /dev/null
+++ b/web/images/sc-deleterow.gif
Binary files differ
diff --git a/web/images/sc-divider1.gif b/web/images/sc-divider1.gif
new file mode 100644
index 0000000..2f3ac5b
--- /dev/null
+++ b/web/images/sc-divider1.gif
Binary files differ
diff --git a/web/images/sc-endcap-h.gif b/web/images/sc-endcap-h.gif
new file mode 100644
index 0000000..900afd6
--- /dev/null
+++ b/web/images/sc-endcap-h.gif
Binary files differ
diff --git a/web/images/sc-endcap-v.gif b/web/images/sc-endcap-v.gif
new file mode 100644
index 0000000..3e6ba4f
--- /dev/null
+++ b/web/images/sc-endcap-v.gif
Binary files differ
diff --git a/web/images/sc-filldown.gif b/web/images/sc-filldown.gif
new file mode 100644
index 0000000..a0d6cba
--- /dev/null
+++ b/web/images/sc-filldown.gif
Binary files differ
diff --git a/web/images/sc-fillright.gif b/web/images/sc-fillright.gif
new file mode 100644
index 0000000..5169a72
--- /dev/null
+++ b/web/images/sc-fillright.gif
Binary files differ
diff --git a/web/images/sc-formuladialog.gif b/web/images/sc-formuladialog.gif
new file mode 100644
index 0000000..404f991
--- /dev/null
+++ b/web/images/sc-formuladialog.gif
Binary files differ
diff --git a/web/images/sc-insertcol.gif b/web/images/sc-insertcol.gif
new file mode 100644
index 0000000..8be72e8
--- /dev/null
+++ b/web/images/sc-insertcol.gif
Binary files differ
diff --git a/web/images/sc-insertrow.gif b/web/images/sc-insertrow.gif
new file mode 100644
index 0000000..28ab390
--- /dev/null
+++ b/web/images/sc-insertrow.gif
Binary files differ
diff --git a/web/images/sc-less-hd.gif b/web/images/sc-less-hd.gif
new file mode 100644
index 0000000..689ebc9
--- /dev/null
+++ b/web/images/sc-less-hd.gif
Binary files differ
diff --git a/web/images/sc-less-hh.gif b/web/images/sc-less-hh.gif
new file mode 100644
index 0000000..f1d978e
--- /dev/null
+++ b/web/images/sc-less-hh.gif
Binary files differ
diff --git a/web/images/sc-less-hn.gif b/web/images/sc-less-hn.gif
new file mode 100644
index 0000000..81245b8
--- /dev/null
+++ b/web/images/sc-less-hn.gif
Binary files differ
diff --git a/web/images/sc-less-vd.gif b/web/images/sc-less-vd.gif
new file mode 100644
index 0000000..605801f
--- /dev/null
+++ b/web/images/sc-less-vd.gif
Binary files differ
diff --git a/web/images/sc-less-vh.gif b/web/images/sc-less-vh.gif
new file mode 100644
index 0000000..aa2de92
--- /dev/null
+++ b/web/images/sc-less-vh.gif
Binary files differ
diff --git a/web/images/sc-less-vn.gif b/web/images/sc-less-vn.gif
new file mode 100644
index 0000000..88290ef
--- /dev/null
+++ b/web/images/sc-less-vn.gif
Binary files differ
diff --git a/web/images/sc-linkdialog.gif b/web/images/sc-linkdialog.gif
new file mode 100644
index 0000000..d206394
--- /dev/null
+++ b/web/images/sc-linkdialog.gif
Binary files differ
diff --git a/web/images/sc-linkout.gif b/web/images/sc-linkout.gif
new file mode 100644
index 0000000..9215def
--- /dev/null
+++ b/web/images/sc-linkout.gif
Binary files differ
diff --git a/web/images/sc-logo.gif b/web/images/sc-logo.gif
new file mode 100644
index 0000000..b76d534
--- /dev/null
+++ b/web/images/sc-logo.gif
Binary files differ
diff --git a/web/images/sc-main-h.gif b/web/images/sc-main-h.gif
new file mode 100644
index 0000000..0b260ed
--- /dev/null
+++ b/web/images/sc-main-h.gif
Binary files differ
diff --git a/web/images/sc-main-v.gif b/web/images/sc-main-v.gif
new file mode 100644
index 0000000..0fb12bb
--- /dev/null
+++ b/web/images/sc-main-v.gif
Binary files differ
diff --git a/web/images/sc-merge.gif b/web/images/sc-merge.gif
new file mode 100644
index 0000000..666b597
--- /dev/null
+++ b/web/images/sc-merge.gif
Binary files differ
diff --git a/web/images/sc-more-hd.gif b/web/images/sc-more-hd.gif
new file mode 100644
index 0000000..2eb56e0
--- /dev/null
+++ b/web/images/sc-more-hd.gif
Binary files differ
diff --git a/web/images/sc-more-hh.gif b/web/images/sc-more-hh.gif
new file mode 100644
index 0000000..fc1059a
--- /dev/null
+++ b/web/images/sc-more-hh.gif
Binary files differ
diff --git a/web/images/sc-more-hn.gif b/web/images/sc-more-hn.gif
new file mode 100644
index 0000000..7e07204
--- /dev/null
+++ b/web/images/sc-more-hn.gif
Binary files differ
diff --git a/web/images/sc-more-vd.gif b/web/images/sc-more-vd.gif
new file mode 100644
index 0000000..055f4ac
--- /dev/null
+++ b/web/images/sc-more-vd.gif
Binary files differ
diff --git a/web/images/sc-more-vh.gif b/web/images/sc-more-vh.gif
new file mode 100644
index 0000000..07acdf7
--- /dev/null
+++ b/web/images/sc-more-vh.gif
Binary files differ
diff --git a/web/images/sc-more-vn.gif b/web/images/sc-more-vn.gif
new file mode 100644
index 0000000..922756d
--- /dev/null
+++ b/web/images/sc-more-vn.gif
Binary files differ
diff --git a/web/images/sc-movefrom.gif b/web/images/sc-movefrom.gif
new file mode 100644
index 0000000..7f665eb
--- /dev/null
+++ b/web/images/sc-movefrom.gif
Binary files differ
diff --git a/web/images/sc-movefromoff.gif b/web/images/sc-movefromoff.gif
new file mode 100644
index 0000000..1760f02
--- /dev/null
+++ b/web/images/sc-movefromoff.gif
Binary files differ
diff --git a/web/images/sc-moveinsert.gif b/web/images/sc-moveinsert.gif
new file mode 100644
index 0000000..f082171
--- /dev/null
+++ b/web/images/sc-moveinsert.gif
Binary files differ
diff --git a/web/images/sc-moveinsertoff.gif b/web/images/sc-moveinsertoff.gif
new file mode 100644
index 0000000..cbb4f30
--- /dev/null
+++ b/web/images/sc-moveinsertoff.gif
Binary files differ
diff --git a/web/images/sc-movepaste.gif b/web/images/sc-movepaste.gif
new file mode 100644
index 0000000..93108d1
--- /dev/null
+++ b/web/images/sc-movepaste.gif
Binary files differ
diff --git a/web/images/sc-movepasteoff.gif b/web/images/sc-movepasteoff.gif
new file mode 100644
index 0000000..254c572
--- /dev/null
+++ b/web/images/sc-movepasteoff.gif
Binary files differ
diff --git a/web/images/sc-multilinedialog.gif b/web/images/sc-multilinedialog.gif
new file mode 100644
index 0000000..1e0d6d6
--- /dev/null
+++ b/web/images/sc-multilinedialog.gif
Binary files differ
diff --git a/web/images/sc-paneslider-h.gif b/web/images/sc-paneslider-h.gif
new file mode 100644
index 0000000..8cb31d4
--- /dev/null
+++ b/web/images/sc-paneslider-h.gif
Binary files differ
diff --git a/web/images/sc-paneslider-v.gif b/web/images/sc-paneslider-v.gif
new file mode 100644
index 0000000..c4bcaee
--- /dev/null
+++ b/web/images/sc-paneslider-v.gif
Binary files differ
diff --git a/web/images/sc-paste.gif b/web/images/sc-paste.gif
new file mode 100644
index 0000000..e39f06c
--- /dev/null
+++ b/web/images/sc-paste.gif
Binary files differ
diff --git a/web/images/sc-pasteformats.gif b/web/images/sc-pasteformats.gif
new file mode 100644
index 0000000..94b2f50
--- /dev/null
+++ b/web/images/sc-pasteformats.gif
Binary files differ
diff --git a/web/images/sc-range2.gif b/web/images/sc-range2.gif
new file mode 100644
index 0000000..e9d69cd
--- /dev/null
+++ b/web/images/sc-range2.gif
Binary files differ
diff --git a/web/images/sc-recalc.gif b/web/images/sc-recalc.gif
new file mode 100644
index 0000000..6e1ebb8
--- /dev/null
+++ b/web/images/sc-recalc.gif
Binary files differ
diff --git a/web/images/sc-redo.gif b/web/images/sc-redo.gif
new file mode 100644
index 0000000..b14aca8
--- /dev/null
+++ b/web/images/sc-redo.gif
Binary files differ
diff --git a/web/images/sc-scrollarea-h.gif b/web/images/sc-scrollarea-h.gif
new file mode 100644
index 0000000..c12715b
--- /dev/null
+++ b/web/images/sc-scrollarea-h.gif
Binary files differ
diff --git a/web/images/sc-scrollarea-v.gif b/web/images/sc-scrollarea-v.gif
new file mode 100644
index 0000000..df99311
--- /dev/null
+++ b/web/images/sc-scrollarea-v.gif
Binary files differ
diff --git a/web/images/sc-sumdialog.gif b/web/images/sc-sumdialog.gif
new file mode 100644
index 0000000..f6bb9ad
--- /dev/null
+++ b/web/images/sc-sumdialog.gif
Binary files differ
diff --git a/web/images/sc-swapcolors.gif b/web/images/sc-swapcolors.gif
new file mode 100644
index 0000000..49c6e80
--- /dev/null
+++ b/web/images/sc-swapcolors.gif
Binary files differ
diff --git a/web/images/sc-thumb-hd.gif b/web/images/sc-thumb-hd.gif
new file mode 100644
index 0000000..e3afbd2
--- /dev/null
+++ b/web/images/sc-thumb-hd.gif
Binary files differ
diff --git a/web/images/sc-thumb-hh.gif b/web/images/sc-thumb-hh.gif
new file mode 100644
index 0000000..47237c2
--- /dev/null
+++ b/web/images/sc-thumb-hh.gif
Binary files differ
diff --git a/web/images/sc-thumb-hn.gif b/web/images/sc-thumb-hn.gif
new file mode 100644
index 0000000..a8e0f08
--- /dev/null
+++ b/web/images/sc-thumb-hn.gif
Binary files differ
diff --git a/web/images/sc-thumb-vd.gif b/web/images/sc-thumb-vd.gif
new file mode 100644
index 0000000..c900734
--- /dev/null
+++ b/web/images/sc-thumb-vd.gif
Binary files differ
diff --git a/web/images/sc-thumb-vh.gif b/web/images/sc-thumb-vh.gif
new file mode 100644
index 0000000..a3229c7
--- /dev/null
+++ b/web/images/sc-thumb-vh.gif
Binary files differ
diff --git a/web/images/sc-thumb-vn.gif b/web/images/sc-thumb-vn.gif
new file mode 100644
index 0000000..d528f43
--- /dev/null
+++ b/web/images/sc-thumb-vn.gif
Binary files differ
diff --git a/web/images/sc-trackingline-h.gif b/web/images/sc-trackingline-h.gif
new file mode 100644
index 0000000..efeff83
--- /dev/null
+++ b/web/images/sc-trackingline-h.gif
Binary files differ
diff --git a/web/images/sc-trackingline-v.gif b/web/images/sc-trackingline-v.gif
new file mode 100644
index 0000000..ce6e8cb
--- /dev/null
+++ b/web/images/sc-trackingline-v.gif
Binary files differ
diff --git a/web/images/sc-undo.gif b/web/images/sc-undo.gif
new file mode 100644
index 0000000..66a07f8
--- /dev/null
+++ b/web/images/sc-undo.gif
Binary files differ
diff --git a/web/images/sc-unmerge.gif b/web/images/sc-unmerge.gif
new file mode 100644
index 0000000..7e0df32
--- /dev/null
+++ b/web/images/sc-unmerge.gif
Binary files differ
diff --git a/web/images/sc-wikiflag.gif b/web/images/sc-wikiflag.gif
new file mode 100644
index 0000000..caf0e3f
--- /dev/null
+++ b/web/images/sc-wikiflag.gif
Binary files differ
diff --git a/web/images/sc-wikilinkflag.gif b/web/images/sc-wikilinkflag.gif
new file mode 100644
index 0000000..5ed3700
--- /dev/null
+++ b/web/images/sc-wikilinkflag.gif
Binary files differ
diff --git a/web/index.html b/web/index.html
new file mode 100644
index 0000000..383ca14
--- /dev/null
+++ b/web/index.html
@@ -0,0 +1,1760 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head id="head">
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>SocialCalc 0.9.1</title>
+<script type="text/javascript" src="socialcalcconstants.js"></script>
+<script type="text/javascript" src="xocom.js"></script>
+<script type="text/javascript" src="socialcalc-3.js"></script>
+<script type="text/javascript" src="socialcalctableeditor.js"></script>
+<script type="text/javascript" src="formatnumber2.js"></script>
+<script type="text/javascript" src="formula1.js"></script>
+<script type="text/javascript" src="socialcalcpopup.js"></script>
+<script type="text/javascript" src="socialcalcspreadsheetcontrol.js"></script>
+<style>
+body, td, input, texarea {font-family:verdana,helvetica,sans-serif;font-size:small;}
+.smaller {font-size:smaller;}
+</style>
+</head>
+<body style="background-color:#FFF;" onresize="spreadsheet.DoOnResize();">
+<div style="margin:8px 0px 10px 0px;">
+ <div id="tableeditor" style="margin:8px 0px 10px 0px;"> </div>
+</div>
+ <div id="msg" onclick="this.innerHTML='&nbsp;';"></div>
+
+ <script>
+
+function addmsg(str) {document.getElementById("msg").innerHTML += ", "+str;}
+function setmsg(str) {document.getElementById("msg").innerHTML = str;}
+
+// window.onerror = function(m, u, l){ addmsg(m+" at line "+l); return true;};
+
+//////////////////////////////
+//
+// OLPC SocialCalc Constants
+//
+//////////////////////////////
+
+//
+// How to localize these for the OLPC/Sugar version:
+//
+// Move these constants into socialcalcconstants.js, along with any others you may want to
+// add for the OLPC version.
+// To let this run standalone with the original English text, with unmodified "standard" SocialCalc socialcalcconstants.js,
+// these appear here in this file.
+//
+
+ SocialCalc.Constants.AllowCtrlS = false; // OLPC doesn't need this and ctrl-s is used for other purposes
+
+ SocialCalc.Constants.s_loc_plain = "Plain";
+ SocialCalc.Constants.s_loc_graph = "Graph";
+ SocialCalc.Constants.s_loc_cells_to_graph = "Cells to Graph";
+ SocialCalc.Constants.s_loc_set_cells_to_graph = "Set Cells To Graph";
+ SocialCalc.Constants.s_loc_graph_type = "Graph Type";
+ SocialCalc.Constants.s_loc_help = "Help";
+ SocialCalc.Constants.s_loc_horizontal_bar="Horizontal Bar";
+ SocialCalc.Constants.s_loc_vertical_bar="Vertical Bar";
+ SocialCalc.Constants.s_loc_pie_chart="Pie Chart";
+ SocialCalc.Constants.s_loc_line_chart="Line Chart";
+ SocialCalc.Constants.s_loc_scatter_chart="Plot Points";
+ SocialCalc.Constants.s_loc_not_set = "Not Set";
+ SocialCalc.Constants.s_loc_unknown_range_name = "Unknown range name";
+ SocialCalc.Constants.s_loc_hide_help = "Hide Help";
+
+ SocialCalc.Constants.s_loc_x="X ";
+ SocialCalc.Constants.s_loc_y="Y ";
+ SocialCalc.Constants.s_loc_max="Max ";
+ SocialCalc.Constants.s_loc_min="Min ";
+ SocialCalc.Constants.s_loc_ok=" OK ";
+
+
+ SocialCalc.Constants.s_GraphRangeNotSelected = 'Select a range of cells with numeric values to graph '+
+ 'and use the OK button above to set the range as the graph range.';
+ //SocialCalc.Constants.s_MainHelpText='here goes the workflow';
+
+ SocialCalc.Constants.s_MainHelpText =
+'<b>HELP TEXT FOLLOWED BY ABOUT TEXT AND LEGAL INFORMATION:</b><br><br> '+
+'Version 5.0<br><br> '+
+'<i>This is a spreadsheet built on SocialCalc JavaScript code. '+
+'</i> '+
+'<br><br> '+
+'You can use the arrow keys and mouse to select cells in a manner similar to traditional spreadsheets. '+
+'This includes using the shift key, as well as dragging. '+
+'<br><br> '+
+'The scrollbars should work in a normal manner. '+
+'Because this is a spreadsheet, you can scroll any amount without needing to create new rows or columns. '+
+'Dragging the thumb to the end of a scrollbar attempts to go to the last row or column where there is/was data. '+
+'The mousewheel is also supported. '+
+'<br><br> '+
+'In addition to the scrollbars there are two pane sliders (that start out at the beginning of the scrollbars) '+
+'that let you "lock" the upper rows or columns to facilitate keeping column and row headers visible when scrolling. '+
+'<br><br> '+
+'You can type values in cells. '+
+'Press Enter, use an arrow key, or click on a cell to finish. '+
+'If you are in a partial formula (e.g., "=1+" or "=SUM(") an arrow key or cell click will '+
+'insert the name of the newly selected cell into the formula, similar to a traditional spreadsheet. '+
+'Cell ranges are separated by typing a ":", or you can use the drag or shift-click range selection methods. '+
+'<br><br> '+
+'The program supports many forms of data, such as numbers, text (preceded by a "\'" if necessary '+
+'to distinguish it from numbers), dates (e.g., "1/2/3"), dollars ("$1,234.50"), time ("3:45"), '+
+'numbers with fractions ("1 1/2"), and "true", "false", and "#N/A". '+
+'A value\'s type determines its displayed format if there is no explicit numeric format set for a cell. '+
+'The program supports a wide variety of formats (including other currencies) through its custom format functionality '+
+'available on the Format tab. '+
+'<br><br> '+
+'Use the Esc key to cancel during edits. '+
+'The Del key deletes the values of the selected cell(s). '+
+'<br><br> '+
+'The 109 formula functions that the June 2007 Open Document Format "Open Formula" specification '+
+'calls the "small group" are available. '+
+'(<b><i>A simple reference to all of the functions is provided when you click the "f()" button on the formula bar.</i></b>) '+
+'The specification says that: "This group includes approximately 100 functions, '+
+'and includes the basic functions that are very widely implemented in spreadsheet applications, '+
+'even in resource-constrained environments."<br><br> '+
+'The definitions of the functions follow common conventions, '+
+'with common syntax similar to many other spreadsheets. '+
+'You can, for example, have a function like IF(B10=B3, "Yes", "No"), where B10 and B3 may contain text values '+
+'(comparisons are not case-sensitive). '+
+'<br><br> '+
+'This release has an HTML version of an editing interface. Most buttons on the toolbar display tooltips when you point to them with the mouse pointer. '+
+'<br><br> '+
+'The program maintains an undo stack accessed through the Undo and Redo buttons on the left of the Edit tab toolbar. '+
+'Right now the stack saves up to 50 steps for undoing. '+
+'The Ctrl-Z key may be used as a shortcut instead of the Undo button. '+
+'<br><br> '+
+'There is a <b>Format</b> tab for accessing all of the format settings, both for individual cells as well '+
+'as for the sheet-wide defaults that are applied to cells without explicit settings for that attribute. '+
+'You can make changes to any or all of the settings and then press the "Save" button in the toolbar above to apply them. '+
+'While the cell settings are only displayed for the current cell, on "Save" the same changes are applied to all cells '+
+'in the currently highlighted range of cells. '+
+'The Sheet settings let you set the default size of columns. To change the width of an individual column click and '+
+'drag in the column header. '+
+'<br><br> '+
+'The <b>Sort</b> tab lets you select a range of cells (which is remembered) to sort, as well as to set which columns '+
+'are used to determine the order and the direction. '+
+'<br><br> '+
+'There is a <b>Comment</b> tab for accessing the optional comment text for the currently selected cell.'+
+'<br><br> '+
+'The <b>Name</b> tab lets you set named ranges that may be used in formulas.'+
+'<br><br> '+
+'The <b>Graph</b> tab displays a graph representation of selected cells. It has its own Help button. '+
+'<br><br> '+
+'The <b>Plain</b> tab shows the sheet rendered without the grid or editing controls. '+
+'<br><br> '+
+'The <b>Clipboard</b> tab lets you view the SocialCalc clipboard in tab-delimited format, and optionally reload it with new data. '+
+'Tab-delimited format is what some browsers and Excel put on the clipboard when you select and then copy cells in a table. '+
+'The Clipboard tab also supports CSV format and the SocialCalc Save format (useful for copying from one sheet to another). '+
+'Reloading from the SocialCalc Save format must be in correct format -- errors can cause SocialCalc to behave badly.<br><br>'+
+'Pressing Ctrl-V when on the Edit tab and not editing a cell assumes that Tab-delimited data is on the regular '+
+'clipboard, loads it into the SocialCalc clipboard, and then "pastes" it starting at the current cell. '+
+'This is an easy way to copy data from a web page into a spreadsheet. '+
+'Similarly, Ctrl-C loads the SocialCalc clipboard and the system clipboard. '+
+'Ctrl-V differs from the Paste button in that it only pastes values and formulas, and not formats. '+
+'<br><br> '+
+'Right now this code is mainly being developed to run under control of a native Python '+
+'application running on the OLPC XO. '+
+'This version, though, can also be run directly in a browser. '+
+'<br><br> '+
+'When the program encounters an error, it may display a message at the bottom of the screen. '+
+'You can click on the message to erase it. '+
+'<br><br> '+
+'Comments can be sent to "socialcalc" at "softwaregarden.com". '+
+'<br><br> '+
+'<hr> '+
+'<b>FUNCTION HELP</b> '+
+'<br><br> '+
+'The following functions are currently supported in formulas (case is ignored in function names): '+
+'<style> '+
+'.helplist dt {font-weight:bold;} '+
+'.helplist dd {padding-bottom:6pt;} '+
+'</style> '+
+'<div style="padding:6pt 0px 0px 1em;" class="helplist"> '+
+'<dl> '+
+'<dt>ABS(value)<dd>Absolute value function. '+
+'<dt>ACOS(value)<dd>Trigonometric arccosine function. '+
+'<dt>AND(value1, value2, ...)<dd>True if all arguments are true. '+
+'<dt>ASIN(value)<dd>Trigonometric arcsine function. '+
+'<dt>ATAN(value)<dd>Trigonometric arctan function. '+
+'<dt>ATAN2(valueX, valueY)<dd>Trigonometric arc tangent function (result is in radians). '+
+'<dt>AVERAGE(value, value, ...)<dd>Averages the values. '+
+'<dt>CHOOSE(index, value1, value2, ...)<dd>Returns the value specified by the index. The values may be ranges of cells. '+
+'<dt>COLUMNS(range)<dd>Returns the number of columns in the range. '+
+'<dt>COS(value)<dd>Trigonometric cosine function (value is in radians). '+
+'<dt>COUNT(value, value, ...)<dd>Counts the number of numeric values, not blank, text, or error. '+
+'<dt>COUNTA(value, value, ...)<dd>Counts the number of non-blank values. '+
+'<dt>COUNTBLANK(value, value, ...)<dd>Counts the number of blank values. (Note: "" is not blank.) '+
+'<dt>COUNTIF(range, criteria)<dd>Counts the number of number of cells in the range that meet the criteria. '+
+'The criteria may be a value ("x", 15, 1+3) or a test (>25). '+
+'<dt>DATE(year, month, day)<dd>Returns the appropriate date value given numbers for year, month, and day. '+
+'For example: DATE(2006,2,1) for February 1, 2006. '+
+'Note: In this program, day "1" is December 31, 1899 and the year 1900 is not a leap year. '+
+'Some programs use January 1, 1900, as day "1" and treat 1900 as a leap year. '+
+'In both cases, though, dates on or after March 1, 1900, are the same. '+
+'<dt>DAVERAGE(databaserange, fieldname, criteriarange)<dd>Averages the values in the specified field in records that meet the criteria. '+
+'<dt>DAY(value)<dd>Returns the day of month for a date value. '+
+'<dt>DCOUNT(databaserange, fieldname, criteriarange)<dd>Counts the number of numeric values, not blank, text, or error, in the specified field in records that meet the criteria. '+
+'<dt>DCOUNTA(databaserange, fieldname, criteriarange)<dd>Counts the number of non-blank values in the specified field in records that meet the criteria. '+
+'<dt>DDB(cost, salvage, lifetime, period [, factor])<dd> '+
+'Returns the amount of depreciation at the given period of time '+
+'(the default factor is 2 for double-declining balance). '+
+'<dt>DEGREES(value)<dd>Converts value in radians in to degrees. '+
+'<dt>DGET(databaserange, fieldname, criteriarange)<dd>Returns the value of the specified field in the single record that meets the criteria. '+
+'<dt>DMAX(databaserange, fieldname, criteriarange)<dd>Returns the maximum of the numeric values in the specified field in records that meet the criteria. '+
+'<dt>DMIN(databaserange, fieldname, criteriarange)<dd>Returns the maximum of the numeric values in the specified field in records that meet the criteria. '+
+'<dt>DPRODUCT(databaserange, fieldname, criteriarange)<dd>Returns the result of multiplying the numeric values in the specified field in records that meet the criteria. '+
+'<dt>DSTDEV(databaserange, fieldname, criteriarange)<dd>Returns the sample standard deviation of the numeric values in the specified field in records that meet the criteria. '+
+'<dt>DSTDEVP(databaserange, fieldname, criteriarange)<dd>Returns the standard deviation of the numeric values in the specified field in records that meet the criteria. '+
+'<dt>DSUM(databaserange, fieldname, criteriarange)<dd>Returns the sum of the numeric values in the specified field in records that meet the criteria. '+
+'<dt>DVAR(databaserange, fieldname, criteriarange)<dd>Returns the sample variance of the numeric values in the specified field in records that meet the criteria. '+
+'<dt>DVARP(databaserange, fieldname, criteriarange)<dd>Returns the variance of the numeric values in the specified field in records that meet the criteria. '+
+'<dt>EVEN(value)<dd>Rounds the value up in magnitude to the nearest even integer. '+
+'<dt>EXACT(value1, value2)<dd>Returns "true" if the values are exactly the same, including case, type, etc. '+
+'<dt>EXP(value)<dd>Returns e raised to the value power. '+
+'<dt>FACT(value)<dd>Returns factorial of the value. '+
+'<dt>FALSE( )<dd>Returns the logical value "false". '+
+'<dt>FIND(string1, string2 [, start])<dd>Returns the starting position within string2 of the first '+
+'occurrence of string1 at or after "start". If start is omitted, 1 is assumed. '+
+'<dt>FV(rate, n, payment, [pv, [paytype]])<dd>Returns the future value of repeated payments of money '+
+'invested at the given rate for the specified number of periods, '+
+'with optional present value (default 0) and payment type '+
+'(default 0 = at end of period, 1 = beginning of period). '+
+'<dt>HLOOKUP(value, range, row, [rangelookup])<dd>Look for the matching value for the given value in the '+
+'range and return the corresponding value in the cell specified by the row offset. '+
+'If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match&lt;=value) instead of exact match. '+
+'<dt>HOUR(value)<dd>Returns the hour portion of a time or date/time value. '+
+'<dt>IF(logical-expression, true-value, false-value)<dd>Results in true-value if logical-expression is TRUE or non-zero, '+
+'otherwise results in false-value. '+
+'<dt>INDEX(range, rownum, colnum)<dd>Returns a cell or range reference for the specified row and column in the range. '+
+'If range is 1-dimensional, then only one of rownum or colnum are needed. '+
+'If range is 2-dimensional and rownum or colnum are zero, a reference to the range of just the specified column or row is returned. '+
+'You can use the returned reference value in a range, e.g., sum(A1:INDEX(A2:A10,4)). '+
+'<dt>INT(value)<dd>Returns the value rounded down to the nearest integer (towards -infinity). '+
+'<dt>IRR(range, [guess])<dd>Returns the interest rate at which the cash flows in the range '+
+'have a net present value of zero. Uses an iterative process that will return '+
+'#NUM! error if it does not converge. '+
+'There may be more than one possible solution. '+
+'Providing the optional guess value may help in certain situations '+
+'where it does not converge or finds an inappropriate solution (the default guess is 10%). '+
+'<dt>ISBLANK(value)<dd>Returns "true" if the value is a reference to a blank cell. '+
+'<dt>ISERR(value)<dd>Returns "true" if the value is of type "Error" but not "NA". '+
+'<dt>ISERROR(value)<dd>Returns "true" if the value is of type "Error". '+
+'<dt>ISLOGICAL(value)<dd>Returns "true" if the value is of type "Logical" (true/false). '+
+'<dt>ISNA(value)<dd>Returns "true" if the value is the error type "NA". '+
+'<dt>ISNONTEXT(value)<dd>Returns "true" if the value is not of type "Text". '+
+'<dt>ISNUMBER(value)<dd>Returns "true" if the value is of type "Number" (including logical values). '+
+'<dt>ISTEXT(value)<dd>Returns "true" if the value is of type "Text". '+
+'<dt>LEFT(text, count)<dd>Returns the specified number of characters from the text value. '+
+'If count is omitted, 1 is assumed. '+
+'<dt>LEN(text)<dd>Returns the number of characters in the text value. '+
+'<dt>LN(value)<dd>Returns the natural logarithm of the value. '+
+'<dt>LOG(value, base)<dd>Returns the logarithm of the value using the specified base. '+
+'<dt>LOG10(value)<dd>Returns the base 10 logarithm of the value. '+
+'<dt>LOWER(text)<dd>Returns the text value with all uppercase characters converted to lowercase. '+
+'<dt>MATCH(value, range, [rangelookup])<dd>Look for the matching value for the given value in the '+
+'range and return position (the first is 1) in that range. '+
+'If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match&lt;=value) instead of exact match. '+
+'If rangelookup is -1, act like 1 but the bracket is match&gt;=value. '+
+'<dt>MAX(value, value, ...)<dd>Returns the maximum of the numeric values. '+
+'<dt>MID(text, start, length)<dd>Returns the specified number of characters from the text value '+
+'starting from the specified position. '+
+'<dt>MIN(value1, value2, ...)<dd>Returns the minimum of the numeric values. '+
+'<dt>MINUTE(value)<dd>Returns the minute portion of a time or date/time value. '+
+'<dt>MOD(value1, value2)<dd>Returns the remainder of the first value divided by the second. '+
+'<dt>MONTH(value)<dd>Returns the month part of a date value. '+
+'<dt>N(value)<dd>Returns the value if it is a numeric value otherwise an error. '+
+'<dt>NA( )<dd>Returns the #N/A error value which propagates through most operations. '+
+'<dt>NOT(value)<dd>Returns FALSE if value is true, and TRUE if it is false. '+
+'<dt>NOW( )<dd>Returns the current date/time. '+
+'<dt>NPER(rate, payment, pv, [fv, [paytype]])<dd>Returns the number of periods at which '+
+'payments invested each period at the given rate with optional future value (default 0) '+
+'and payment type (default 0 = at end of period, 1 = beginning of period) '+
+'has the given present value. '+
+'<dt>NPV(rate, value1, value2, ...)<dd>Returns the net present value of cash flows '+
+'(which may be individual values and/or ranges) at the given rate. '+
+'The flows are positive if income, negative if paid out, and are assumed at the end of '+
+'each period. '+
+'<dt>ODD(value)<dd>Rounds the value up in magnitude to the nearest odd integer. '+
+'<dt>OR(value1, value2,...)<dd>True if any argument is true '+
+'<dt>PI( )<dd>The value 3.1415926... '+
+'<dt>PMT(rate, n, pv, [fv, [paytype]])<dd>Returns the amount of each payment that must be '+
+'invested at the given rate for the specified number of periods '+
+'to have the specified present value, with optional future value (default 0) '+
+'and payment type (default 0 = at end of period, 1 = beginning of period). '+
+'<dt>POWER(value1, value2)<dd>Returns the first value raised to the second value power. '+
+'<dt>PRODUCT(value1, value2, ...)<dd>Returns the result of multiplying the numeric values. '+
+'<dt>PROPER(value)<dd>Returns the text value with the first letter of each word '+
+'converted to uppercase and the others to lowercase. '+
+'<dt>PV(rate, n, payment, [fv, [paytype]])<dd>Returns the present value of '+
+'the given number of payments each invested at the given rate, '+
+'with optional future value (default 0) '+
+'and payment type (default 0 = at end of period, 1 = beginning of period). '+
+'<dt>RADIANS(value)<dd>Converts value in degrees into radians. '+
+'<dt>RATE(n, payment, pv, [fv, [paytype, [guess]]])<dd>Returns the rate at which '+
+'the given number of payments each invested at the given rate has the '+
+'specified present value, with optional future value (default 0) '+
+'and payment type (default 0 = at end of period, 1 = beginning of period). '+
+'Uses an iterative process that will return #NUM! error if it does not converge. '+
+'There may be more than one possible solution. '+
+'Providing the optional guess value may help in certain situations '+
+'where it does not converge or finds an inappropriate solution (the default guess is 10%). '+
+'<dt>REPLACE(text1, start, length, text2)<dd>Returns text1 with the specified number of characters '+
+'starting from the specified position replaced by text2. '+
+'<dt>REPT(text, count)<dd>Returns the text repeated the specified number of times. '+
+'<dt>RIGHT(text, count)<dd>Returns the specified number of characters from the text value '+
+'starting from the end. '+
+'If count is omitted, 1 is assumed. '+
+'<dt>ROUND(value, [precision])<dd>Rounds the value to the specified number of decimal places. '+
+'If precision is negative, then round to powers of 10. '+
+'The default precision is 0 (round to integer). '+
+'<dt>ROWS(range)<dd>Returns the number of rows in the range. '+
+'<dt>SECOND(value)<dd>Returns the second portion of a time or date/time value (truncated to an integer). '+
+'<dt>SIN(value)<dd>Trigonometric sine function (value is in radians) '+
+'<dt>SLN(cost, salvage, lifetime, period)<dd> '+
+'Returns the amount of depreciation at each period of time using the straight-line method. '+
+'<dt>SQRT(value)<dd>Square root of the value '+
+'<dt>STDEV(value, value, ...)<dd>Returns the sample standard deviation of the numeric values. '+
+'<dt>STDEVP(value, value, ...)<dd>Returns the standard deviation of the numeric values. '+
+'<dt>SUBSTITUTE(text1, oldtext, newtext [, occurrence])<dd>Returns text1 with the all occurrences '+
+'of oldtext replaced by newtext. If "occurrence" is present, then only that occurrence is replaced. '+
+'<dt>SUM(value, value, ...)<dd>Adds the numeric values. The values to the sum function may be ranges in the form similar to A1:B5. '+
+'<dt>SUMIF(range1, criteria [, range2])<dd>Sums the numeric values of cells in the range that meet the criteria. '+
+'The criteria may be a value ("x", 15, 1+3) or a test (>25). '+
+'If range2 is present, then range1 is tested and the corresponding range2 value is summed. '+
+'<dt>SYD(cost, salvage, lifetime, period)<dd>Depreciation by Sum of Year\'s Digits method. '+
+'<dt>T(value)<dd>Returns the text value or else a null string. '+
+'<dt>TAN(value)<dd>Trigonometric tangent function (value is in radians) '+
+'<dt>TIME(hour, minute, second)<dd>Returns the time value given the specified '+
+'hour, minute, and second. '+
+'<dt>TODAY( )<dd>Returns the current date (an integer). '+
+'Note: In this program, day "1" is December 31, 1899 and the year 1900 is not a leap year. '+
+'Some programs use January 1, 1900, as day "1" and treat 1900 as a leap year. '+
+'In both cases, though, dates on or after March 1, 1900, are the same. '+
+'<dt>TRIM(text)<dd>Returns the text value with leading, trailing, and repeated spaces removed. '+
+'<dt>TRUE( )<dd>Returns the logical value "true". '+
+'<dt>TRUNC(value, precision)<dd>Truncates the value to the specified number of decimal places. '+
+'If precision is negative, truncate to powers of 10. '+
+'<dt>UPPER(text)<dd>Returns the text value with all lowercase characters converted to uppercase. '+
+'<dt>VALUE(value)<dd>Converts the specified text value into a numeric value. '+
+'Various forms that look like numbers (including digits followed by %, forms that look like '+
+'dates, etc.) are handled. '+
+'This may not handle all of the forms accepted by other spreadsheets and may be '+
+'locale dependent. '+
+'<dt>VAR(value, value, ...)<dd>Returns the sample variance of the numeric values. '+
+'<dt>VARP(value, value, ...)<dd>Returns the variance of the numeric values. '+
+'<dt>VLOOKUP(value, range, col, [rangelookup])<dd>Look for the matching value for the given value in the '+
+'range and return the corresponding value in the cell specified by the column offset. '+
+'If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match&lt;=value) instead of exact match. '+
+'<dt>WEEKDAY(date, [type])<dd>Returns the day of week specified by the date value. '+
+'If type is 1 (the default), Sunday is day and Saturday is day 7. '+
+'If type is 2, Monday is day 1 and Sunday is day 7. '+
+'If type is 3, Monday is day 0 and Sunday is day 6. '+
+'<dt>YEAR(date)<dd>Returns the year part of a date value. '+
+'</dl> '+
+'<hr>ABOUT TEXT:<br><br> '+
+'<i>This is the 5th version of the SocialCalc Activity for the Sugar environment, OLPC\'s software paradigm. '+
+'<br><br> '+
+'For more information, see the SocialCalc on Sugar page at the SEETA website - http://seeta.in/j/products-and-services/socialcalc-on-sugar.html'+
+' and Software Garden OLPC Home Page (www.peapodcast.com/sgi/olpc). </i> '+
+'<br><br> '+
+'(c) Copyright 2009 Socialtext, Inc.<br> '+
+'All Rights Reserved. '+
+'<br><br> '+
+'This product consists of components licensed under different licenses. '+
+'Some are licensed under the Common Public Attribution License (CPAL) and '+
+'others under the Artistic License 2.0. '+
+'Check the contents of each file for a statement of the license for that file. '+
+'Files without license information (e.g., image files) are licensed under the Artistic License 2.0. '+
+'The source code comes with a LEGAL.txt file and a LICENSE.txt file. '+
+'For more information, see the web page listed above. '+
+'<br><br> '+
+'The software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY '+
+'KIND, either express or implied. See the License for the specific language governing rights and '+
+'limitations under the License. '+
+'<br><br> '+
+'The OLPC part of the project was started by Manusheel Gupta, Managing Director of SEETA (Software for Education, Entertainment and Training'+
+' Activities - http://seeta.in), K.S. Preeti, community friend of SEETA (http://seeta.in) and alumnus from Netaji Subhas Institute of Technology,'+
+' University of Delhi with guidance from Walter Bender, Oversight Board Member at Sugar Labs.'+
+'<br><br> '+
+'The OLPC part of the project is presently coordinated by Manusheel Gupta, Managing Director of SEETA (http://seeta.in) and Vijit Singh, '+
+'Software Engineer, Products and Services at SEETA (http://seeta.in). '+
+'<br><br> '+
+'The XOCom library, which is used to communicate between Python based Sugar environment and JavaScript based SocialCalc was developed by '+
+'Luke Closs from Socialtext Inc. and/or by K.S. Preeti (depending upon the version). '+
+'<br><br> '+
+'The pie, line and bar chart tools was developed by Nicholas Doiron, an engineering student from Carnegie Mellon University, U.S.A under'+
+'the guidance of Manusheel Gupta.'+
+'<br><br> '+
+'Collaboration over the mesh network was developed by Vijit Singh under the guidance of Manusheel Gupta.'+
+'<br><br> '+
+'Interoperability between SocialCalc activity and other popular spreadsheet formats like Excel and Lotus Notes have been developed '+
+'by Vijit Singh and Mahesh Chand Sharma from SEETA (http://seeta.in) under the guidance of Manusheel Gupta. '+
+'<br><br> '+
+'Localization infrastructure has been developed by Vijit Singh under the guidance of Manusheel Gupta with pointers from Dan Bricklin. '+
+'<br><br> '+
+'Spanish translation has been undertaken by Claudia Urrea and Reuben Caron from One Laptop Per Child Columbia with support from '+
+'Manusheel Gupta, and integrated to the SocialCalc activity by Diksha Khatri from SEETA (http://seeta.in) and Vijit Singh. '+
+'<br><br> '+
+'Localization in Chinese (simplified), French, Hindi, German and Portuguese were undertaken by Diksha Khatri and Lakky Rawat from SEETA'+
+' (http://seeta.in) using google translator, and integrated to the SocialCalc code by Vijit Singh. '+
+'<br><br> '+
+'Localization in Afrikaans, Japanese, Arabic and Russian was undertaken by Sakshi Chawla from SEETA (http://seeta.in) using google '+
+'translator, and integrated to the SocialCalc code by Vijit Singh. '+
+'<br><br> '+
+'The JavaScript SocialCalc code was initially coded by Dan Bricklin of Software Garden, Inc., for Socialtext, Inc.<br> '+
+'Based in part on the SocialCalc 1.1.0 code written in Perl.<br> '+
+'The SocialCalc 1.1.0 code was:<br> '+
+'<blockquote> '+
+' Portions (c) Copyright 2005, 2006, 2007 Software Garden, Inc.<br> '+
+' All Rights Reserved.<br> '+
+' Portions (c) Copyright 2007 Socialtext, Inc.<br> '+
+' All Rights Reserved.<br> '+
+'</blockquote> '+
+'The Perl SocialCalc started as modifications to the wikiCalc(R) program, version 1.0.<br> '+
+'wikiCalc 1.0 was written by Software Garden, Inc.<br> '+
+'<br><br> '+
+'<span class="smaller">wikiCalc, Garden, and Software Garden are registered trademarks of Software Garden, Inc.<br> '+
+'Socialtext, SocialCalc, and the Socialtext logo and Dreamcatcher are trademarks of Socialtext, Inc.<br> '+
+'Dan Bricklin\'s is a registered trademark of Daniel Bricklin.</span>';
+
+
+/////////////////////////////
+
+ // Make socialcalcpopup.js localizable (it doesn't assume SocialCalc.Constants)
+
+ SocialCalc.Popup.LocalizeString = SocialCalc.LocalizeString;
+
+ // Create the spreadsheet control, but don't initialize yet
+
+ var spreadsheet = new SocialCalc.SpreadsheetControl();
+ var savestr = "";
+
+ // Set up the tabs we want
+
+ // Remove Audit
+
+ spreadsheet.tabs.splice(spreadsheet.tabnums.audit, 1);
+
+ spreadsheet.tabnums = {};
+ for (var i=0; i<spreadsheet.tabs.length; i++) {
+ spreadsheet.tabnums[spreadsheet.tabs[i].name] = i;
+ }
+
+ // Add Plain
+
+ spreadsheet.tabnums.plain = spreadsheet.tabs.length;
+ spreadsheet.tabs.push({name: "plain", text: SocialCalc.Constants.s_loc_plain, html:
+ '<div id="%id.plaintools" style="display:none;">'+
+ ' <div style="%tbt.">&nbsp;</div>'+
+ '</div>',
+ view: "plain",
+ onclick:
+ function(s, t) {
+ s.views.plain.element.innerHTML = s.CreateSheetHTML();
+ },
+ onclickFocus: true
+ });
+
+ spreadsheet.views["plain"] = {name: "plain",
+ divStyle: "border:1px solid black;overflow:auto;",
+ html: 'Plain View'
+ };
+
+ // Add Graph
+SocialCalc.GraphTypesInfo = {
+
+ displayorder: ["verticalbar","horizontalbar","piechart","linechart","scatterchart"],
+ verticalbar: {display: SocialCalc.Constants.s_loc_vertical_bar, func: GraphVerticalBar},
+ horizontalbar: {display: SocialCalc.Constants.s_loc_horizontal_bar, func: GraphHorizontalBar},
+ piechart: {display: SocialCalc.Constants.s_loc_pie_chart, func: MakePieChart},
+ linechart: {display: SocialCalc.Constants.s_loc_line_chart, func: MakeLineChart},
+ scatterchart: {display: SocialCalc.Constants.s_loc_scatter_chart, func: MakeScatterChart}
+ };
+ spreadsheet.tabnums.graph = spreadsheet.tabs.length;
+ spreadsheet.tabs.push({name: "graph", text: SocialCalc.Constants.s_loc_graph, html:
+ '<div id="%id.graphtools" style="display:none;">'+
+ ' <div style="%tbt.">'+
+ ' <table cellspacing="0" cellpadding="0"><tr>'+
+ ' <td style="vertical-align:middle;padding-right:32px;padding-left:16px;">'+
+ ' <div style="%tbt.">'+SocialCalc.Constants.s_loc_cells_to_graph+'</div>'+
+ ' <div id="%id.graphrange" style="font-weight:bold;">'+SocialCalc.Constants.s_loc_not_set+'</div>'+
+ ' </td>'+
+ ' <td style="vertical-align:top;padding-right:32px;">'+
+ ' <div style="%tbt.">'+SocialCalc.Constants.s_loc_set_cells_to_graph+'</div>'+
+ ' <select id="%id.graphlist" size="1" onfocus="%s.CmdGotFocus(this);"><option selected>['+SocialCalc.Constants.s_loc_Xselect_rangeX+']</option></select>'+
+ ' </td>'+
+ ' <td style="vertical-align:middle;padding-right:4px;">'+
+ ' <div style="%tbt.">'+SocialCalc.Constants.s_loc_graph_type+'</div>'+
+ ' <select id="%id.graphtype" size="1" onchange="GraphChanged(this);" onfocus="%s.CmdGotFocus(this);"></select>'+
+ ' <input type="button" value="'+SocialCalc.Constants.s_loc_ok+'" onclick="GraphSetCells();" style="font-size:x-small;">'+
+ ' </div>'+
+ ' </td>'+
+ ' <td style="vertical-align:middle;padding-right:16px;">'+
+ ' <div style="%tbt.">&nbsp;</div>'+
+ ' <input id="%id.graphhelp" type="button" onclick="DoGraph(true);" value="'+SocialCalc.Constants.s_loc_help+'" style="font-size:x-small;">'+
+ ' </div>'+
+ ' </td>'+
+ ' <td style="vertical-align:middle;padding-right:16px;">'+
+ ' '+SocialCalc.Constants.s_loc_min+SocialCalc.Constants.s_loc_x+'<input id="%id.graphMinX" onchange="MinMaxChanged(this,0);" onfocus="%s.CmdGotFocus(this);" size=5/>'+
+ ' '+SocialCalc.Constants.s_loc_max+SocialCalc.Constants.s_loc_x+'<input id="%id.graphMaxX" onchange="MinMaxChanged(this,1);" onfocus="%s.CmdGotFocus(this);" size=5/><br/>'+
+ ' '+SocialCalc.Constants.s_loc_min+SocialCalc.Constants.s_loc_y+'<input id="%id.graphMinY" onchange="MinMaxChanged(this,2);" onfocus="%s.CmdGotFocus(this);" size=5/>'+
+ ' '+SocialCalc.Constants.s_loc_max+SocialCalc.Constants.s_loc_y+'<input id="%id.graphMaxY" onchange="MinMaxChanged(this,3);" onfocus="%s.CmdGotFocus(this);" size=5/>'+
+ ' </div>'+
+ ' </td>'+
+ ' </tr></table>'+
+ ' </div>'+
+ '</div>',
+ view: "graph",
+ onclick: GraphOnClick,
+ onclickFocus: true
+ });
+
+ spreadsheet.views["graph"] = {name: "graph", divStyle: "overflow:auto;", values: {},
+ html: '<div style="padding:6px;">Graph View</div>'
+ };
+
+ spreadsheet.editor.SettingsCallbacks.graph = {save: GraphSave, load: GraphLoad};
+
+ // Add Help
+
+ spreadsheet.tabnums.help = spreadsheet.tabs.length;
+ spreadsheet.tabs.push({name: "help", text: SocialCalc.Constants.s_loc_help, html:
+ '<div id="%id.helptools" style="display:none;">'+
+ ' <div style="%tbt.">&nbsp;</div>'+
+ '</div>',
+ view: "help",
+ onclick: DoHelp,
+ onclickFocus: true
+ });
+
+ spreadsheet.views["help"] = {name: "help",
+ divStyle: "border:1px solid black;overflow:auto;",
+ html: '<div style="padding:6px;">Help View</div>'
+ };
+
+ // Initialize the Spreadsheet Control and display it
+
+ //spreadsheet.InitializeSpreadsheetControl("tableeditor");
+ //spreadsheet.ExecuteCommand('redisplay', '');
+
+ // Done initialization
+
+//
+// * * * FUNCTIONS * * *
+//
+
+function gup(nm){nm=nm.replace(/[\[]/,"\\\[").replace(/]\]]/,"\\\]");var rxS="[\\?&]"+nm+"=([^&#]*)";var rx=new RegExp(rxS);var rs=rx.exec(window.location.href);if(!rs){return null}else{return rs[1]}}
+
+/*XO.ajaxPort = gup("ajax");
+XO.cometPort = gup("comet");
+
+ var localscript = document.createElement("script");
+ localscript.src="http://127.0.0.1:"+XO.ajaxPort+"/cometor.js";
+ localscript.type="text/javascript";
+ document.getElementById("head").appendChild(localscript);
+*/
+//
+// Example of how to get the serialized data
+//
+XO.register('write', function () {
+ return spreadsheet.CreateSpreadsheetSave();
+});
+
+//
+// Example of how to reload the serialized data
+//
+// Don't do this when a command or displaying is being executed. It wipes out the sheet without checking.
+// (If you do this on an initial load, skip the 'redisplay' above.)
+//
+
+function replaceAlls(src,older,newer){
+ while(src.indexOf(older)!=-1){
+ src=src.replace(older,newer);
+ }
+ return src;
+}
+
+XO.register('read', function (savestr) {
+ savestr = replaceAlls(savestr,"DECNEWLINE","\\n")
+ savestr = replaceAlls(savestr,"NEWLINE","\n")
+ var parts = spreadsheet.DecodeSpreadsheetSave(savestr);
+ if (parts) {
+ if (parts.sheet) {
+ spreadsheet.sheet.ResetSheet();
+ spreadsheet.ParseSheetSave(savestr.substring(parts.sheet.start, parts.sheet.end));
+ }
+ if (parts.edit) {
+ spreadsheet.editor.LoadEditorSettings(savestr.substring(parts.edit.start, parts.edit.end));
+ }
+ }
+ if (spreadsheet.editor.context.sheetobj.attribs.recalc=="off") {
+ spreadsheet.ExecuteCommand('redisplay', '');
+ }
+ else {
+ spreadsheet.ExecuteCommand('recalc', '');
+ }
+ });
+
+
+// * * * * * * * * * *
+//
+// Graphing Framework
+//
+// * * * * * * * * * *
+
+//
+// To add a new graph type, add it's short name to the SocialCalc.GraphTypesInfo.displayorder array
+// in the order you wish the types to appear and add an item with its display text
+// and the function to call to implement it.
+//
+// To make them localizable, make sure that there is a "s_loc_lowercase_name" constant in
+// socialcalcconstants.js for each display name, as well as any strings it uses.
+// In this sample, only the "Hide Help" button names are localized. The help
+// text itself is not. You'd probably want some mechanism for that.
+//
+
+function GraphOnClick(s, t) {
+
+ var SCLoc = SocialCalc.LocalizeString;
+
+ var name, i;
+ var namelist = [];
+ var nl = document.getElementById(s.idPrefix+"graphlist");
+ s.editor.RangeChangeCallback.graph = UpdateGraphRangeProposal;
+
+ for (name in s.sheet.names) {
+ namelist.push(name);
+ }
+ namelist.sort();
+ nl.length = 0;
+ nl.options[0] = new Option(SCLoc("[select range]"));
+ for (i=0; i<namelist.length; i++) {
+ name = namelist[i];
+ nl.options[i+1] = new Option(name, name);
+ if (name == s.graphrange) {
+ nl.options[i+1].selected = true;
+ }
+ }
+ if (s.graphrange == "") {
+ nl.options[0].selected = true;
+ }
+
+ UpdateGraphRangeProposal(s.editor);
+
+ nl = document.getElementById(s.idPrefix+"graphtype");
+ nl.length = 0;
+ for (i=0; i<SocialCalc.GraphTypesInfo.displayorder.length; i++) {
+ name = SocialCalc.GraphTypesInfo.displayorder[i];
+ nl.options[i] = new Option(SCLoc(SocialCalc.GraphTypesInfo[name].display), name);
+ if (name == s.graphtype) {
+ nl.options[i].selected = true;
+ }
+ }
+ if (!s.graphtype) {
+ nl.options[0].selected = true;
+ s.graphtype = nl.options[0].value;
+ }
+
+ //SocialCalc.KeyboardFocus(); // NOTE: Well, this was commented in Nick's one but not in Dan's one, can't say why?
+
+ DoGraph(false,true);
+
+ return;
+
+ }
+
+function UpdateGraphRangeProposal(editor) {
+
+ var ele = document.getElementById(SocialCalc.GetSpreadsheetControlObject().idPrefix+"graphlist");
+ if (editor.range.hasrange) {
+ ele.options[0].text = SocialCalc.crToCoord(editor.range.left, editor.range.top) + ":" +
+ SocialCalc.crToCoord(editor.range.right, editor.range.bottom);
+ }
+ else {
+ ele.options[0].text = SocialCalc.LocalizeString("[select range]");
+ }
+
+ }
+
+function GraphSetCells() {
+
+ var lele, ele;
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var editor = spreadsheet.editor;
+
+ lele = document.getElementById(spreadsheet.idPrefix+"graphlist");
+ if (lele.selectedIndex==0) {
+ if (editor.range.hasrange) {
+ spreadsheet.graphrange = SocialCalc.crToCoord(editor.range.left, editor.range.top) + ":" +
+ SocialCalc.crToCoord(editor.range.right, editor.range.bottom);
+ }
+ else {
+ spreadsheet.graphrange = editor.ecell.coord+":"+editor.ecell.coord;
+ }
+ }
+ else {
+ spreadsheet.graphrange = lele.options[lele.selectedIndex].value;
+ }
+ ele = document.getElementById(spreadsheet.idPrefix+"graphrange");
+ ele.innerHTML = spreadsheet.graphrange;
+ //SocialCalc.KeyboardFocus();
+
+ DoGraph(false,false);
+
+ return;
+
+ }
+
+// NOTE: this is resize thing is there in the nick version but not in the dan one, so just confirm whether it should be there
+function DoGraph(helpflag,isResize) {
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var editor = spreadsheet.editor;
+
+ var gview = spreadsheet.views.graph.element;
+
+ var ginfo = SocialCalc.GraphTypesInfo[spreadsheet.graphtype];
+
+ var gfunc = ginfo.func;
+
+ if (!spreadsheet.graphrange) {
+ if (gfunc && helpflag) {
+ gfunc(spreadsheet, null, gview, spreadsheet.graphtype, helpflag, isResize);
+ }
+ else {
+ gview.innerHTML = '<div style="padding:30px;font-weight:bold;">'+SocialCalc.Constants.s_GraphRangeNotSelected+'</div>';
+
+ // NOTE: The below line was present there in the earlier version of it nick one, and not in dan one, still confirm it....
+ //gview.innerHTML = '<div style="padding:30px;font-weight:bold;">Select a range of cells with numeric values to graph '+
+ // 'and use the OK button above to set the range as the graph range.</div>';
+ }
+ return;
+ }
+
+ var grange = spreadsheet.graphrange;
+ var nrange, rparts;
+
+ if (grange && grange.indexOf(":")==-1) { // graphing range is a named range
+ nrange = SocialCalc.Formula.LookupName(spreadsheet.sheet, grange || "");
+ if (nrange.type != "range") {
+ gview.innerHTML = SocialCalc.LocalizeString("Unknown range name")+": "+grange;
+ return;
+ }
+ rparts = nrange.value.match(/^(.*)\|(.*)\|$/);
+ grange = rparts[1] + ":" + rparts[2];
+ }
+
+ var prange = SocialCalc.ParseRange(grange);
+ var range = {};
+ if (prange.cr1.col <= prange.cr2.col) {
+ range.left = prange.cr1.col;
+ range.right = prange.cr2.col;
+ }
+ else {
+ range.left = prange.cr2.col;
+ range.right = prange.cr1.col;
+ }
+ if (prange.cr1.row <= prange.cr2.row) {
+ range.top = prange.cr1.row;
+ range.bottom = prange.cr2.row;
+ }
+ else {
+ range.top = prange.cr2.row;
+ range.bottom = prange.cr1.row;
+ }
+
+ if (gfunc) {
+ gfunc(spreadsheet, range, gview, spreadsheet.graphtype, helpflag, isResize);
+ }
+
+ return;
+
+ }
+
+function GraphChanged(gtobj) {
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+
+ spreadsheet.graphtype = gtobj.options[gtobj.selectedIndex].value;
+
+ DoGraph(false,false);
+ try{
+ GraphSetCells();
+ }
+ catch(e){}
+
+ }
+
+ // NOTE: was there in the nick version and not in dan one, so confirm
+function MinMaxChanged(minmaxobj,index){
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ switch(index){
+ case 0:
+ spreadsheet.graphMinX = minmaxobj.value;
+ break;
+ case 1:
+ spreadsheet.graphMaxX = minmaxobj.value;
+ break;
+ case 2:
+ spreadsheet.graphMinY = minmaxobj.value;
+ break;
+ case 3:
+ spreadsheet.graphMaxY = minmaxobj.value;
+ break;
+ }
+
+ DoGraph(false,true);
+}
+
+// NOTE: a bit of change than the original one.
+function GraphSave(editor, setting) {
+ // Format is:
+ // graph:range:[graphrange]:type:[graphtype]:minmax:[minX,maxX,minY,maxY]
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var gtype = spreadsheet.graphtype || "";
+
+ var str = "graph:range:"+SocialCalc.encodeForSave(spreadsheet.graphrange)+":type:"+SocialCalc.encodeForSave(gtype);
+ str += ":minmax:" + SocialCalc.encodeForSave(spreadsheet.graphMinX + "," + spreadsheet.graphMaxX + "," + spreadsheet.graphMinY + "," + spreadsheet.graphMaxY) + "\n";
+
+ return str;
+
+ }
+
+// NOTE: extra case of minmax has also been added
+function GraphLoad(editor, setting, line, flags) {
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var parts, i;
+
+ parts = line.split(":");
+
+ for (i=1; i<parts.length; i+=2) {
+ switch (parts[i]) {
+ case "range":
+ spreadsheet.graphrange = SocialCalc.decodeFromSave(parts[i+1]);
+ break;
+ case "type":
+ spreadsheet.graphtype = SocialCalc.decodeFromSave(parts[i+1]);
+ break;
+ case "minmax":
+ var splitMinMax = SocialCalc.decodeFromSave(parts[i+1]).split(",");
+ spreadsheet.graphMinX = splitMinMax[0];
+ document.getElementById("SocialCalc-graphMinX").value = spreadsheet.graphMinX;
+ spreadsheet.graphMaxX = splitMinMax[1];
+ document.getElementById("SocialCalc-graphMaxX").value = spreadsheet.graphMaxX;
+ spreadsheet.graphMinY = splitMinMax[2];
+ document.getElementById("SocialCalc-graphMinY").value = spreadsheet.graphMinY;
+ spreadsheet.graphMaxY = splitMinMax[3];
+ document.getElementById("SocialCalc-graphMaxY").value = spreadsheet.graphMaxY;
+ break;
+ }
+ }
+ try{
+ GraphSetCells();
+ }
+ catch(e){}
+ return true;
+
+ }
+
+
+//
+// Graphing Functions are called with (spreadsheet, range, gview, gtype, helpflag)
+//
+
+var standardColors=["rgb(204,131,167)","rgb(213,94,0)","rgb(0,114,178)","rgb(240,228,66)","rgb(0,158,115)","rgb(86,180,233)","rgb(230,159,0)","rgb(0,0,0)"];
+
+function colorFix(rrggbb){
+ rrggbb=rrggbb.replace("rgb(","").replace(")","").split(",")
+ for(var a=0;a<3;a++){
+ var fdigit;
+ var sdigit;
+ if(rrggbb[a] > 15){
+ fdigit = Math.floor(rrggbb[a]/16);
+ if(fdigit==10){fdigit="a";}
+ else if(fdigit==11){fdigit="b";}
+ else if(fdigit==12){fdigit="c";}
+ else if(fdigit==13){fdigit="d";}
+ else if(fdigit==14){fdigit="e";}
+ else if(fdigit>=15){fdigit="f";}
+ }
+ else{
+ fdigit="0";
+ }
+ sdigit=rrggbb[a]%16;
+ if(sdigit==10){sdigit="a";}
+ else if(sdigit==11){sdigit="b";}
+ else if(sdigit==12){sdigit="c";}
+ else if(sdigit==13){sdigit="d";}
+ else if(sdigit==14){sdigit="e";}
+ else if(sdigit>=15){sdigit="f";}
+ rrggbb[a]=(fdigit+"_").replace("_",sdigit);
+ }
+ return rrggbb[0]+""+rrggbb[1]+""+rrggbb[2];
+}
+
+// NOTE: from here till dohelp function, all code has been added from the nick part, it is basically where nick has coded the different types of graphs
+// , some changes might also be there which I will mention in b/w this code also, like the strings used have also been sent for localization as in
+// graphVerticalBar function
+
+function GraphVerticalBar(spreadsheet, range, gview, gtype, helpflag) {
+
+ var maxheight, totalwidth, nitems, byrow, maxval, minval, i, cr, cr1, cell, val, extra, eachwidth, str, thisbar;
+ var values = [];
+ var labels = [];
+
+ //SocialCalc.Constants.s_MainHelpText=' reaching in the vertical fn'
+
+ if (helpflag || !range) {
+
+ str = '<input type="button" value='+SocialCalc.Constants.s_loc_hide_help+' onclick="DoGraph(false,false);"><br><br>'+
+ 'This is the help text for graph type: '+SocialCalc.GraphTypesInfo[gtype].display+'.<br><br>'+
+ 'The <b>Graph</b> tab displays a bar graph of the cells which have been selected '+
+ '(either in a single row across or column down). '+
+ 'If the row above (or column to the left) of the selection has values, those values are used as labels. '+
+ 'Otherwise the cells value is used as a label. '+
+ '<br><br><input type="button" value='+SocialCalc.Constants.s_loc_hide_help+' onclick="DoGraph(false,false);">';
+
+ str = SocialCalc.LocalizeSubstrings(str);
+
+ gview.innerHTML = str;
+
+ return;
+ }
+
+ if (range.left==range.right) { // down
+ nitems = range.bottom - range.top + 1;
+ byrow = true;
+ }
+ else {
+ nitems = range.right - range.left + 1;
+ byrow = false;
+ }
+
+ str = "";
+
+ maxheight = (spreadsheet.height-spreadsheet.nonviewheight)-60;
+ totalwidth = spreadsheet.width-30;
+
+ minval = null;
+ maxval = null;
+ var barColors = [];
+
+ for (i=0; i<nitems; i++) {
+ cr = byrow ? SocialCalc.rcColname(range.left)+(i+range.top) : SocialCalc.rcColname(i+range.left)+range.top;
+ cr1 = byrow ? SocialCalc.rcColname(range.left-1 || 1)+(i+range.top) : SocialCalc.rcColname(i+range.left)+(range.top-1 || 1);
+ cell = spreadsheet.sheet.GetAssuredCell(cr);
+ //$("secret").innerHtml = cell.color;
+ if (cell.valuetype.charAt(0) == "n") {
+ val = cell.datavalue - 0;
+ if (maxval==null || maxval<val) maxval = val;
+ if (minval==null || minval>val) minval = val;
+ values.push(val);
+ //cell=spreadsheet.sheet.GetAssuredCell(cr1);
+ var inColors = false;
+ if(cell.color){
+ for(var c=0; c<barColors.length; c++){
+ if(barColors[c] == cell.color){
+ inColors=true;
+ break;
+ }
+ }
+ if(!inColors){
+ //barColors.push(spreadsheet.sheet.colors[cell.color]);
+ barColors.push(cell.color);
+ }
+ else{
+ barColors.push("rand");
+ }
+ }
+ else if(barColors.length<8){
+ barColors.push(standardColors[barColors.length])
+ }
+ else{
+ barColors.push("rand");
+ }
+ cell = spreadsheet.sheet.GetAssuredCell(cr1);
+ if ((range.right==range.left || range.top==range.bottom) && (cell.valuetype.charAt(0) == "t" || cell.valuetype.charAt(0) == "n")) {
+ labels.push(cell.datavalue+"");
+ }
+ else {
+ labels.push(val+"");
+ }
+ }
+ } if(maxval < 0){ maxval = 0; }
+ if(minval > 0){ minval = 0; }
+ str = '<table><tr><td><canvas id="myBarCanvas" width="1100px" height="500px" style="border:1px solid black;"></canvas></td></tr></table>';
+ gview.innerHTML = str;
+ var profChartVals = new Array();
+ var profChartLabels = new Array();
+
+ var canv = document.getElementById("myBarCanvas");
+ var ctx = canv.getContext('2d');
+ //deprecated mozTextStyle is used by the laptop's rendering engine
+ ctx.mozTextStyle = "10pt bold Arial";
+ var maxheight = canv.height - 60;
+ totalwidth = canv.width;
+ var colors = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
+ var barColor;
+ if(barColors[0]=="rand"){
+ barColor = colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + ''+ colors[Math.round(Math.random()*14)]+ '' + colors[Math.round(Math.random()*14)]+ '' + colors[Math.round(Math.random()*14)]+ '' + colors[Math.round(Math.random()*14)];
+ }
+ else{
+ if(barColors[0].indexOf("rgb")==-1){
+ barColor = colorFix(spreadsheet.sheet.colors[barColors[0]]);
+ }
+ else{
+ barColor=colorFix(barColors[0]);
+ }
+ }
+ ctx.fillStyle = "#" + barColor;
+ var colorList = [barColor];
+ eachwidth = Math.floor(totalwidth / (values.length || 1))-4 || 1;
+ var zeroLine = maxheight * (maxval / (maxval-minval)) + 20;
+ ctx.lineWidth = 5;
+ ctx.moveTo(0,zeroLine);
+ ctx.lineTo(canv.width,zeroLine);
+ ctx.stroke();
+ var yScale = maxheight / (maxval-minval);
+ for (i=0; i<values.length; i++) {
+ ctx.fillRect(i*eachwidth,zeroLine-yScale*values[i],eachwidth,yScale*values[i]);
+ profChartVals.push(Math.floor((values[i]-minval) * yScale / 3.4));
+ profChartLabels.push(labels[i]);
+ barColor = colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + ''+ colors[Math.round(Math.random()*14)]+ '' + colors[Math.round(Math.random()*14)]+ '' + colors[Math.round(Math.random()*14)]+ '' + colors[Math.round(Math.random()*14)];
+ if(i+1<barColors.length){
+ if(barColors[i+1]!="rand"){
+ if(barColors[i+1].indexOf("rgb")==-1){
+ var barColorRGB = spreadsheet.sheet.colors[barColors[i+1]];
+ // [r,g,b]->RRGGBB
+ barColor=colorFix(barColorRGB);
+ }
+ else{
+ barColor=colorFix(barColors[i+1]);
+ }
+ }
+ }
+ //document.getElementById("secret").innerHTML+=";"+barColor;
+ ctx.fillStyle = "#" + barColor;
+ colorList.push(barColor);
+ }
+ ctx.strokeStyle = "#000000";
+ ctx.fillStyle = "#000000";
+ if(values[0] > 0){
+ ctx.translate(5,zeroLine+22);
+ }
+ else{
+ ctx.translate(5,zeroLine-15);
+ }
+ ctx.mozDrawText(labels[0]);
+ for (i=1; i<values.length; i++){
+ if((values[i] > 0)&&(values[i-1] < 0)){
+ ctx.translate(eachwidth,37);
+ }
+ else{
+ if((values[i] < 0)&&(values[i-1] > 0)){
+ ctx.translate(eachwidth,-37);
+ }
+ else{
+ ctx.translate(eachwidth,0);
+ }
+ }
+ ctx.mozDrawText(labels[i]);
+ }
+
+ //order a Google Charts API image
+ //var gChart = document.getElementById("googleBarChart");
+ var zeroLine = (-1 * minval) * yScale / 340;
+ //profChartUrl = 'chs=300x250&cht=bvg&chd=t:' + profChartVals.join(",") + "&chxt=x,y&chxl=0:|" + profChartLabels.join("|") + "|&chxr=1," + minval + "," + maxval + "&chp=" + zeroLine + "&chbh=a&chm=r,000000,0," + zeroLine + "," + (zeroLine + 0.005) + "&chco=" + colorList.join("|");
+ //gChart.innerHTML = '<iframe src="urlJump.html?img=' + escape(profChartUrl) + '" style="width:315px;height:270px;"></iframe>';
+ }
+ function GraphHorizontalBar(spreadsheet, range, gview, gtype, helpflag) {
+
+ var maxheight, totalwidth, color, nitems, byrow, maxval, minval, i, cr, cr1, cell, val, extra, eachwidth, str, thisbar;
+ var values = [];
+ var labels = [];
+ var barColors=[];
+
+ if (helpflag || !range) {
+ str = '<input type="button" value='+SocialCalc.Constants.s_loc_hide_help+' onclick="DoGraph(false,false);"><br><br>'+
+ 'This is the help text for graph type: '+SocialCalc.GraphTypesInfo[gtype].display+'.<br><br>'+
+ 'The <b>Graph</b> tab displays a very simple bar graph representation of the cells currently selected as a range to graph '+
+ '(either in a single row across or column down). '+
+ 'If the range is a single row or column, and if the row above (or column to the left) has values, those values are used as labels. '+
+ 'Otherwise the cell coordinates are used (e.g., B5). '+
+ 'This is a very early, minimal implementation for demonstration purposes. '+
+ '<br><br><input type="button" value='+SocialCalc.Constants.s_loc_hide_help+' onclick="DoGraph(false,false);">';
+
+ gview.innerHTML = str;
+
+ return;
+ }
+
+ if (range.left==range.right) { // down
+ nitems = range.bottom - range.top + 1;
+ byrow = true;
+ }
+ else {
+ nitems = range.right - range.left + 1;
+ byrow = false;
+ }
+
+ str = "";
+
+ maxheight = (spreadsheet.height-spreadsheet.nonviewheight)-50;
+ totalwidth = spreadsheet.width-30;
+ minval = null;
+ maxval = null;
+
+ for (i=0; i<nitems; i++) {
+ cr = byrow ? SocialCalc.rcColname(range.left)+(i+range.top) : SocialCalc.rcColname(i+range.left)+range.top;
+ cr1 = byrow ? SocialCalc.rcColname(range.left-1 || 1)+(i+range.top) : SocialCalc.rcColname(i+range.left)+(range.top-1 || 1);
+ cell = spreadsheet.sheet.GetAssuredCell(cr);
+ if (cell.valuetype.charAt(0) == "n") {
+ val = cell.datavalue - 0;
+ if (maxval==null || maxval<val) maxval = val;
+ if (minval==null || minval>val) minval = val;
+ values.push(val);
+ if(cell.color){
+ barColors.push(cell.color);
+ }
+ else if(barColors.length<8){
+ barColors.push(standardColors[barColors.length])
+ }
+ else{
+ barColors.push("rand");
+ }
+ cell = spreadsheet.sheet.GetAssuredCell(cr1);
+ if ((range.right==range.left || range.top==range.bottom) && (cell.valuetype.charAt(0) == "t" || cell.valuetype.charAt(0) == "n")) {
+ labels.push(cell.datavalue+"");
+ }
+ else {
+ labels.push(val+"");
+ }
+ }
+ }
+ if(maxval < 0){ maxval = 0; }
+ if(minval > 0){ minval = 0; }
+ str = '<table><tr><td><canvas id="myBarCanvas" width="1100px" height="500px" style="border:1px solid black;"></canvas></td></tr></table>';
+ gview.innerHTML = str;
+ var profChartVals = new Array();
+ var profChartLabels = new Array();
+
+ var canv = document.getElementById("myBarCanvas");
+ var ctx = canv.getContext('2d');
+ //deprecated mozTextStyle is used by the laptop's rendering engine
+ ctx.mozTextStyle = "10pt bold Arial";
+ var maxheight = canv.height - 60;
+ totalwidth = canv.width;
+ var colors = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
+ var barColor= colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + ''+ colors[Math.round(Math.random()*14)]+ '' + colors[Math.round(Math.random()*14)]+ '' + colors[Math.round(Math.random()*14)]+ '' + colors[Math.round(Math.random()*14)];
+ if(barColors[0]!="rand"){
+ if(barColors[0].indexOf("rgb")==-1){
+ barColor=colorFix(spreadsheet.sheet.colors[1*barColors[0]]);
+ }
+ else{
+ barColor=colorFix(barColors[0]);
+ }
+ }
+ ctx.fillStyle = "#" + barColor;
+ var colorList = [barColor];
+ eachwidth = Math.floor(maxheight / (values.length || 1))-4 || 1;
+ var zeroLine = totalwidth * (maxval / (maxval-minval)) - 5;
+ zeroLine = canv.width - zeroLine + 100;
+ ctx.lineWidth = 5;
+ ctx.moveTo(zeroLine,0);
+ ctx.lineTo(zeroLine,canv.height);
+ ctx.stroke();
+ var yScale = totalwidth / (maxval-minval) * 11/16;
+ for (i=0; i<values.length; i++) {
+ ctx.fillRect(zeroLine+yScale*values[i],i*eachwidth+30,-1*yScale*values[i],eachwidth);
+ profChartVals.push(Math.floor((values[i]-minval) * yScale / 4.4));
+ profChartLabels.push(labels[i]);
+ var barColor = colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + ''+ colors[Math.round(Math.random()*14)]+ '' + colors[Math.round(Math.random()*14)]+ '' + colors[Math.round(Math.random()*14)]+ '' + colors[Math.round(Math.random()*14)];
+ if(i+1<barColors.length){
+ if(barColors[i+1]!="rand"){
+ if(barColors[i+1].indexOf("rgb")==-1){
+ barColor=colorFix(spreadsheet.sheet.colors[1*barColors[i+1]]);
+ }
+ else{
+ barColor=colorFix(barColors[i+1]);
+ }
+ }
+ }
+ ctx.fillStyle = "#" + barColor;
+ colorList.push(barColor);
+ }
+ ctx.strokeStyle = "#000000";
+ ctx.fillStyle = "#000000";
+ if(values[0] > 0){
+ ctx.translate(0,45);
+ }
+ else{
+ ctx.translate(0,45);
+ }
+ ctx.mozDrawText(labels[0]);
+ for (i=1; i<values.length; i++){
+ if((values[i] > 0)&&(values[i-1] < 0)){
+ ctx.translate(0,eachwidth);
+ }
+ else{
+ if((values[i] < 0)&&(values[i-1] > 0)){
+ ctx.translate(0,eachwidth);
+ }
+ else{
+ ctx.translate(0,eachwidth);
+ }
+ }
+ ctx.mozDrawText(labels[i]);
+ }
+
+ //order a Google Charts API image
+ //var gChart = document.getElementById("googleBarChart");
+ //var zeroLine = (-1*minval) * yScale / (canv.width);
+ //profChartUrl = 'chs=300x250&cht=bhs&chd=t:' + profChartVals.join(",") + "&chxt=x,y&chxl=1:|" + profChartLabels.reverse().join("|") + "|&chxr=0," + minval + "," + maxval + "&chp=" + zeroLine + "&chbh=a&chm=r,000000,0," + zeroLine + "," + (zeroLine + 0.005) + "&chco=" + colorList.join("|");
+ //gChart.innerHTML = '<iframe src="urlJump.html?img=' + escape(profChartUrl) + '" style="width:315px;height:270px;"></iframe>';
+ }
+
+function MakePieChart(spreadsheet, range, gview, gtype, helpflag){
+ var maxheight, totalwidth, color, nitems, byrow, maxval, minval, i, cr, cr1, cell, val, extra, eachwidth, str, thisbar;
+ var values = [];
+ var labels = [];
+ var total = 0;
+ var pieColors=[];
+
+ // collect the selected values and labels
+ if (range.left==range.right) { // down
+ nitems = range.bottom - range.top + 1;
+ byrow = true;
+ }
+ else {
+ nitems = range.right - range.left + 1;
+ byrow = false;
+ }
+
+ // find total to be distributed over 2 Pi radians
+ for (i=0; i<nitems; i++) {
+ cr = byrow ? SocialCalc.rcColname(range.left)+(i+range.top) : SocialCalc.rcColname(i+range.left)+range.top;
+ cr1 = byrow ? SocialCalc.rcColname(range.left-1 || 1)+(i+range.top) : SocialCalc.rcColname(i+range.left)+(range.top-1 || 1);
+ cell = spreadsheet.sheet.GetAssuredCell(cr);
+ if (cell.valuetype.charAt(0) == "n") {
+ val = cell.datavalue - 0;
+ total += val;
+ values.push(val);
+ if(cell.color){
+ pieColors.push(cell.color);
+ }
+ else if(pieColors.length<8){
+ pieColors.push(standardColors[pieColors.length])
+ }
+ else{
+ pieColors.push("rand");
+ }
+ cell = spreadsheet.sheet.GetAssuredCell(cr1);
+ if ((range.right==range.left || range.top==range.bottom) && (cell.valuetype.charAt(0) == "t" || cell.valuetype.charAt(0) == "n")) {
+ labels.push(cell.datavalue+"");
+ }
+ else {
+ labels.push(val+"");
+ }
+ }
+ }
+ str = '<table><tr><td><img id="canvImg" style="border:1px solid black;" src=""/><canvas id="myCanvas" style="display:none;" width="1100px" height="500px"></canvas></td></tr></table>';
+ gview.innerHTML = str;
+ var profChartUrl = "";
+ var profChartLabels = "";
+
+ var canv = document.getElementById("myCanvas");
+ var ctx = canv.getContext('2d');
+ //deprecated mozTextStyle is used by the laptop's rendering engine
+ ctx.mozTextStyle = "10pt Arial";
+ var centerX = canv.width/2;
+ var centerY = canv.height/2;
+ var rad = centerY - 50;
+ var textRad = rad * 1.1;
+ var lastStart = 0;
+ //colors are #000 - #fff
+ colors = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
+
+ for (i=0; i<values.length; i++) {
+ //prepare to draw a piece
+ ctx.beginPath();
+ ctx.moveTo(centerX,centerY);
+
+ // choose a random color (fix so it doesn't change every time the graph is viewed)
+ var arcColor= "#" + colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + ''+ colors[Math.round(Math.random()*14)];
+ if(pieColors[i]!="rand"){
+ if(pieColors[i].indexOf("rgb")==-1){
+ arcColor=colorFix(spreadsheet.sheet.colors[1*pieColors[i]]);
+ }
+ else{
+ arcColor=colorFix(pieColors[i]);
+ }
+ arcColor="#"+arcColor;
+ }
+ ctx.fillStyle = arcColor;
+
+ //set the size of this arc piece in radians
+ var arcRads = 2 * Math.PI * (values[i] / total);
+ profChartUrl += "," + values[i];
+
+ //draw arc
+ ctx.arc(centerX,centerY,rad,lastStart,lastStart+arcRads,false);
+ ctx.closePath();
+ ctx.fill();
+
+ //draw label: leftBias gives text more room if it's on the left part of the circle
+ ctx.fillStyle = "black";
+ var centralRad = lastStart + 0.5 * arcRads;
+ var leftBias = 0;
+ if((centralRad > 1.5)&&(centralRad < 4.6)){ leftBias = 95; }
+ else{
+ leftBias = -95;
+ }
+
+ ctx.translate(centerX + Math.cos(centralRad) * textRad - leftBias, centerY + Math.sin(centralRad) * textRad);
+ //deprecated mozDrawText is needed for the laptop's rendering engine
+ ctx.mozDrawText(labels[i] + " (" + Math.round(values[i]/total*100) + "%)");
+ //this operation allows canvas to continue drawing
+ ctx.translate(-1*centerX - Math.cos(centralRad)*textRad + leftBias,-1*centerY - Math.sin(centralRad) * textRad);
+ ctx.fillRect(1,1,1,1);
+ ctx.closePath();
+ profChartLabels += "|" + labels[i];
+
+ //prepare for next arc
+ lastStart += arcRads;
+ }
+ //replace HTML canvas with its PNG image
+ var realCanv = document.getElementById("canvImg");
+ realCanv.src = canv.toDataURL();
+
+ //request a Google Charts API image
+ //var gChart = document.getElementById("googleChart");
+ //profChartUrl = 'chs=300x145&cht=p&chd=t:' + profChartUrl.substring(1) + '&chl=' + profChartLabels.substring(1);
+ //gChart.innerHTML = '<iframe src="urlJump.html?img=' + escape(profChartUrl) + '" style="width:315px;height:270px;"></iframe>';
+}
+
+function MakeLineChart(spreadsheet, range, gview, gtype, helpflag, isResize){
+ var nitems, byrow, maxval, minval, i, cr, cr1, cell, val, extra, str, maxX, minX;
+ var values = [];
+ var labels = [];
+ var total = 0;
+ var colors = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
+ var shapes = ["s","o","c"];
+ var lineColors = [];
+
+ // collect the selected values and labels
+ if (range.left==range.right) { // down
+ nitems = range.bottom - range.top + 1;
+ byrow = true;
+ }
+ else {
+ nitems = range.right - range.left + 1;
+ byrow = false;
+ }
+
+ //if the user has set the min/max values, use them
+ if(isResize){
+ try{ minX = 1 * document.getElementById("SocialCalc-graphMinX").value; }
+ catch(e){ minX = null; }
+ try{ maxX = 1 * document.getElementById("SocialCalc-graphMaxX").value; }
+ catch(e){ maxX = null; }
+ try{ minval = 1 * document.getElementById("SocialCalc-graphMinY").value; }
+ catch(e){ minval = null; }
+ try{ maxval = 1 * document.getElementById("SocialCalc-graphMaxY").value; }
+ catch(e){ maxval = null; }
+ }
+
+ var evenlySpaced = false;
+ for (i=0; i<nitems; i++) {
+ cr = byrow ? SocialCalc.rcColname(range.left)+(i+range.top) : SocialCalc.rcColname(i+range.left)+range.top;
+ cr1 = byrow ? SocialCalc.rcColname(range.left-1 || 1)+(i+range.top) : SocialCalc.rcColname(i+range.left)+(range.top-1 || 1);
+ cell = spreadsheet.sheet.GetAssuredCell(cr);
+ if (cell.valuetype.charAt(0) == "n") {
+ val = cell.datavalue - 0;
+ if ((maxval==null || maxval<val) && !isResize){ maxval = val; }
+ if ((minval==null || minval>val) && !isResize){ minval = val; }
+ values.push(val);
+ if(cell.color){
+ lineColors.push(""+cell.color);
+ }
+ else if(lineColors.length<8){
+ lineColors.push(standardColors[lineColors.length])
+ }
+ else{
+ lineColors.push("rand");
+ }
+ cell = spreadsheet.sheet.GetAssuredCell(cr1);
+ if ((range.right==range.left || range.top==range.bottom) && (cell.valuetype.charAt(0) == "t" || cell.valuetype.charAt(0) == "n")) {
+ labels.push(cell.datavalue+"");
+ if ((maxX==null || maxX<cell.datavalue) && !isResize){ maxX = cell.datavalue; }
+ if ((minX==null || minX>cell.datavalue) && !isResize){ minX = cell.datavalue; }
+ }
+ else {
+ labels.push(cr);
+ evenlySpaced = true;
+ }
+ }
+ }
+ // create evenly-spaced X values if none were given
+ if(evenlySpaced){
+ for(var i=0; i<values.length; i++){
+ labels[i] = i;
+ }
+ if(!isResize){
+ minX = 0;
+ maxX = values.length - 1;
+ }
+ }
+ if(!isResize){
+ maxX=Math.max(maxX,0);
+ maxval=Math.max(maxval,0);
+ minX=Math.min(minX,0);
+ minval=Math.min(minval,0);
+ }
+ str = '<canvas id="myLineCanvas" style="border:1px solid black;" width="1100px" height="500px"></canvas>';
+ gview.innerHTML = str;
+ //gview.innerHTML=lineColors.join(";");
+
+ // let the user set the min and max for X and Y axes
+ if(!isResize){
+ document.getElementById("SocialCalc-graphMinX").value = minX;
+ spreadsheet.graphMinX = minX;
+ document.getElementById("SocialCalc-graphMaxX").value = maxX;
+ spreadsheet.graphMaxX = maxX;
+ document.getElementById("SocialCalc-graphMinY").value = minval;
+ spreadsheet.graphMinY = minval;
+ document.getElementById("SocialCalc-graphMaxY").value = maxval;
+ spreadsheet.graphMaxY = maxval;
+ }
+
+ var canv = document.getElementById("myLineCanvas");
+ var ctx = canv.getContext('2d');
+ var scaleFactorX = (canv.width - 40) / (maxX - minX);
+ var scaleFactorY = (canv.height - 40) / (maxval - minval);
+ var lastX = scaleFactorX * (labels[0] - minX) + 20;
+ var lastY = scaleFactorY * (values[0] - minval) + 20;
+ var profChart = [Math.floor(lastX/canv.width*100),Math.floor(lastY/canv.height*100)];
+ var topY = canv.height;
+ var drawColor;
+ if(lineColors[0]=="rand"){
+ drawColor= "#" + colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)];
+ }
+ else{
+ if(lineColors[0].indexOf("rgb")==-1){
+ drawColor=colorFix(spreadsheet.sheet.colors[1*lineColors[0]]);
+ }
+ else{
+ drawColor=colorFix(lineColors[0]);
+ }
+ drawColor="#"+drawColor;
+ //$("secretl").innerHTML=";"+drawColor;
+ }
+ var colorArray = [drawColor.replace("#","")];
+ ctx.strokeStyle = drawColor;
+ ctx.fillStyle = drawColor;
+ ctx.fillRect(lastX-3,topY-lastY-3,6,6);
+ ctx.beginPath();
+ for (i=1; i<values.length; i++) {
+
+ //determine if next X is part of the same line (greater than the last X value)
+ if((labels[i] * 1) > (labels[i-1] * 1)){
+ //draw line to the next point
+ ctx.moveTo(lastX,topY-lastY);
+ ctx.lineTo((scaleFactorX * (labels[i] - minX)) + 20, topY-(scaleFactorY * (values[i] - minval) + 20));
+ ctx.stroke();
+ }
+ else{
+ //start a new line
+ if(lineColors[i]=="rand"){
+ drawColor="#" + colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)];
+ }
+ else{
+ if(lineColors[i].indexOf("rgb")==-1){
+ drawColor=colorFix(spreadsheet.sheet.colors[1*lineColors[i]]);
+ }
+ else{
+ drawColor=colorFix(lineColors[i]);
+ }
+ drawColor="#"+drawColor;
+ }
+ ctx.strokeStyle = drawColor;
+ ctx.fillStyle = drawColor;
+ colorArray.push(drawColor.replace("#",""));
+ ctx.beginPath();
+ }
+
+ //calculate canvas coordinates for next point
+ lastX = scaleFactorX * (labels[i] - minX) + 20;
+ lastY = scaleFactorY * (values[i] - minval) + 20;
+ // draw different shapes
+ if((colorArray.length-1)%3 == 0){
+ //square
+ ctx.fillRect(lastX-3,topY-lastY-3,6,6);
+ }
+ else if((colorArray.length-1)%3 == 1){
+ //circle
+ ctx.beginPath();
+ ctx.arc(lastX,topY-lastY,3,0,Math.PI * 2,false);
+ ctx.fill();
+ }
+ else{
+ // + sign
+ ctx.fillRect(lastX,topY-lastY-3,2,8);
+ ctx.fillRect(lastX-3,topY-lastY,8,2);
+ }
+ // update Google chart
+ if((labels[i] * 1) > (labels[i-1] * 1)){
+ //add a point to the current line
+ profChart[profChart.length-2] += "," + Math.floor(lastX/canv.width*100);
+ profChart[profChart.length-1] += "," + Math.floor(lastY/canv.height*100);
+ }
+ else{
+ //add a new line
+ var newIndex = profChart.length;
+ profChart[newIndex] = Math.floor(lastX/canv.width*100);
+ profChart[newIndex+1] = Math.floor(lastY/canv.height*100);
+ }
+ }
+ ctx.stroke();
+ //colorMarkings stores the colors of the lines and orders input points to be marked
+ var colorMarkings = "&chco=" + colorArray.join(",") + "&chm=";
+ for(var i=0;i<colorArray.length;i++){
+ if(i%3 == 0){
+ //square
+ colorArray[i] = "s," + colorArray[i] + "," + i + ",-1,6";
+ }
+ else if(i%3 == 1){
+ //circle
+ colorArray[i] = "o," + colorArray[i] + "," + i + ",-1,6";
+ }
+ else{
+ // + sign
+ colorArray[i] = "c," + colorArray[i] + "," + i + ",-1,10";
+ }
+ }
+ colorMarkings += colorArray.join("|");
+ if(minval <= 0 && maxval >= 0){
+ //draw X=0 axis on both canvas and Google chart
+ ctx.beginPath();
+ ctx.strokeStyle = "#000000";
+ ctx.moveTo(0,canv.height-(scaleFactorY * -1 * minval + 20));
+ ctx.lineTo(canv.width,canv.height-(scaleFactorY * -1 * minval + 20));
+ ctx.stroke();
+ var graphPlace = 1-((canv.height-(scaleFactorY * -1 * minval + 20)) / canv.height);
+ colorMarkings += "|r,000000,0," + graphPlace + "," + (graphPlace + 0.005)
+ }
+ if(minX <= 0 && maxX >= 0){
+ //draw Y=0 axis on both canvas and Google chart
+ ctx.beginPath();
+ ctx.strokeStyle = "#000000";
+ ctx.moveTo(scaleFactorX * -1 * minX + 20, 0);
+ ctx.lineTo(scaleFactorX * -1 * minX + 20, canv.height);
+ ctx.stroke();
+ var graphPlace = (scaleFactorX * -1 * minX + 20) / canv.width;
+ colorMarkings += "|R,000000,0," + graphPlace + "," + (graphPlace + 0.005)
+ }
+ //var gChart = document.getElementById("googleLineChart");
+ //add margin to sides of Google chart
+ minX -= (maxX-minX)/23;
+ maxX += (maxX-minX)/23;
+ minval -= (maxval-minval)/18;
+ maxval += (maxval-minval)/18;
+ //profChartUrl = 'chs=300x250' + colorMarkings + '&cht=lxy&chxt=x,y&chxr=0,' + minX + ',' + maxX + '|1,' + minval + ',' + maxval + '&chd=t:' + profChart.join("|");
+ //gChart.innerHTML = '<iframe src="urlJump.html?img=' + escape(profChartUrl) + '" style="width:315px;height:270px;"></iframe>';
+}
+
+function MakeScatterChart(spreadsheet, range, gview, gtype, helpflag, isResize){
+ var nitems, byrow, maxval, minval, i, cr, cr1, cell, val, extra, str, maxX, minX, dotSizes;
+ var values = [];
+ var labels = [];
+ var total = 0;
+ var dotColors=[];
+ var colors = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
+
+ // collect the selected values and labels
+ if (range.left==range.right) { // down
+ nitems = range.bottom - range.top + 1;
+ byrow = true;
+ }
+ else {
+ nitems = range.right - range.left + 1;
+ byrow = false;
+ }
+
+ //if the user has set the min/max values, use them
+ if(isResize){
+ try{ minX = 1 * document.getElementById("SocialCalc-graphMinX").value; }
+ catch(e){ minX = null; }
+ try{ maxX = 1 * document.getElementById("SocialCalc-graphMaxX").value; }
+ catch(e){ maxX = null; }
+ try{ minval = 1 * document.getElementById("SocialCalc-graphMinY").value; }
+ catch(e){ minval = null; }
+ try{ maxval = 1 * document.getElementById("SocialCalc-graphMaxY").value; }
+ catch(e){ maxval = null; }
+ }
+
+ var evenlySpaced = false;
+ dotSizes = new Array();
+ for (i=0; i<nitems; i++) {
+ cr = byrow ? SocialCalc.rcColname(range.left)+(i+range.top) : SocialCalc.rcColname(i+range.left)+range.top;
+ cr1 = byrow ? SocialCalc.rcColname(range.left-1 || 1)+(i+range.top) : SocialCalc.rcColname(i+range.left)+(range.top-1 || 1);
+ cr2 = byrow ? SocialCalc.rcColname(range.left+1 || 2)+(i+range.top) : SocialCalc.rcColname(i+range.left)+(range.top+1 || 2);
+ cell = spreadsheet.sheet.GetAssuredCell(cr);
+ if (cell.valuetype.charAt(0) == "n") {
+ val = cell.datavalue - 0;
+ if ((maxval==null || maxval<val) && !isResize){ maxval = val; }
+ if ((minval==null || minval>val) && !isResize){ minval = val; }
+ values.push(val);
+ if(cell.color){
+ dotColors.push(cell.color);
+ }
+ else if(dotColors.length<8){
+ dotColors.push(standardColors[dotColors.length])
+ }
+ else{
+ dotColors.push("rand");
+ }
+ cell = spreadsheet.sheet.GetAssuredCell(cr1);
+ if ((range.right==range.left || range.top==range.bottom) && (cell.valuetype.charAt(0) == "t" || cell.valuetype.charAt(0) == "n")) {
+ labels.push(cell.datavalue+"");
+ if ((maxX==null || maxX<cell.datavalue) && !isResize){ maxX = cell.datavalue; }
+ if ((minX==null || minX>cell.datavalue) && !isResize){ minX = cell.datavalue; }
+ }
+ else {
+ labels.push(cr);
+ evenlySpaced = true;
+ }
+ cell = spreadsheet.sheet.GetAssuredCell(cr2);
+ if ((range.right==range.left || range.top==range.bottom) && (cell.valuetype.charAt(0) == "t" || cell.valuetype.charAt(0) == "n")) {
+ dotSizes.push(cell.datavalue+"");
+ }
+ else {
+ dotSizes.push("5");
+ }
+ }
+ }
+ // create evenly-spaced X values if none were given
+ if(evenlySpaced){
+ for(var i=0; i<values.length; i++){
+ labels[i] = i;
+ }
+ if(!isResize){
+ minX = 0;
+ maxX = values.length - 1;
+ }
+ }
+
+ str = '<canvas id="myScatterCanvas" style="border:1px solid black;" width="1100px" height="500px"></canvas>';
+ str += '<div id="scatterChartScales"><input type="button" id="autoScaleButton" value="Reset" onclick=""/>X-min:<input id="minPlotX" onchange="" size=5/>X-max:<input id="maxPlotX" onchange="" size=5/>Y-min:<input id="minPlotY" onchange="" size=5/>Y-max:<input id="maxPlotY" onchange="" size=5/></div>';
+ gview.innerHTML = str;
+
+ // let the user set the min and max for X and Y axes
+ if(!isResize){
+ minX=Math.min(minX,0);
+ minval=Math.min(minval,0);
+ maxX=Math.max(maxX,0);
+ maxval=Math.max(maxval,0);
+ document.getElementById("SocialCalc-graphMinX").value = minX;
+ spreadsheet.graphMinX = minX;
+ document.getElementById("SocialCalc-graphMaxX").value = maxX;
+ spreadsheet.graphMaxX = maxX;
+ document.getElementById("SocialCalc-graphMinY").value = minval;
+ spreadsheet.graphMinY = minval;
+ document.getElementById("SocialCalc-graphMaxY").value = maxval;
+ spreadsheet.graphMaxY = maxval;
+ }
+
+ var canv = document.getElementById("myScatterCanvas");
+ var ctx = canv.getContext('2d');
+ //support for 5 distinctly colored data sets
+ var scaleFactorX = (canv.width - 40) / (maxX - minX);
+ var scaleFactorY = (canv.height - 40) / (maxval - minval);
+ var lastX = scaleFactorX * (labels[0] - minX) + 20;
+ var lastY = scaleFactorY * (values[0] - minval) + 20;
+ var profChart = [Math.floor(lastX/canv.width*100),Math.floor(lastY/canv.height*100), dotSizes[0] * 10];
+ var topY = canv.height;
+ var drawColor= "#" + colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)] + '' + colors[Math.round(Math.random()*14)];
+ if(dotColors[0]!="rand"){
+ if(dotColors[0].indexOf("rgb")==-1){
+ drawColor=colorFix(spreadsheet.sheet.colors[1*dotColors[0]]);
+ }
+ else{
+ drawColor=colorFix(dotColors[0]);
+ }
+ drawColor="#"+drawColor;
+ }
+ ctx.fillStyle = drawColor;
+ ctx.beginPath();
+ ctx.arc(lastX,topY-lastY,dotSizes[0],0,2*Math.PI,false);
+ ctx.fill();
+ for (i=1; i<values.length; i++) {
+ // draw next point
+ if(dotColors[i]!="rand"){
+ if(dotColors[i].indexOf("rgb")==-1){
+ drawColor=colorFix(spreadsheet.sheet.colors[1*dotColors[i]]);
+ }
+ else{
+ drawColor=colorFix(dotColors[i]);
+ }
+ ctx.fillStyle="#"+drawColor;
+ }
+ ctx.moveTo(lastX,topY-lastY);
+ lastX = scaleFactorX * (labels[i] - minX) + 20;
+ lastY = scaleFactorY * (values[i] - minval) + 20;
+ ctx.beginPath();
+ ctx.arc(lastX,topY-lastY,dotSizes[i],0,2*Math.PI,false);
+ ctx.fill();
+
+ // update Google chart
+ profChart[profChart.length-3] += "," + Math.floor(lastX/canv.width*100);
+ profChart[profChart.length-2] += "," + Math.floor(lastY/canv.height*100);
+ profChart[profChart.length-1] += "," + (dotSizes[i] * 10)
+ }
+ //colorMarkings sets the colors of the data sets
+ var colorMarkings = '&chm=o,' + drawColor.replace("#","") + ',0,-1,10';
+ if(minval <= 0 && maxval >= 0){
+ //draw X=0 axis on both canvas and Google chart
+ ctx.beginPath();
+ ctx.strokeStyle = "#000000";
+ ctx.moveTo(0,canv.height-(scaleFactorY * -1 * minval + 20));
+ ctx.lineTo(canv.width,canv.height-(scaleFactorY * -1 * minval + 20));
+ ctx.stroke();
+ var graphPlace = 1-((canv.height-(scaleFactorY * -1 * minval + 20)) / canv.height);
+ colorMarkings += "|r,000000,0," + graphPlace + "," + (graphPlace + 0.005)
+ }
+ if(minX <= 0 && maxX >= 0){
+ //draw Y=0 axis on both canvas and Google chart
+ ctx.beginPath();
+ ctx.strokeStyle = "#000000";
+ ctx.moveTo(scaleFactorX * -1 * minX + 20, 0);
+ ctx.lineTo(scaleFactorX * -1 * minX + 20, canv.height);
+ ctx.stroke();
+ var graphPlace = (scaleFactorX * -1 * minX + 20) / canv.width;
+ colorMarkings += "|R,000000,0," + graphPlace + "," + (graphPlace + 0.005)
+ }
+ //var gChart = document.getElementById("googleScatterChart");
+ //add margin to sides of Google chart
+ minX -= (maxX-minX)/23;
+ maxX += (maxX-minX)/23;
+ minval -= (maxval-minval)/18;
+ maxval += (maxval-minval)/18;
+ //profChartUrl = 'chs=300x250' + colorMarkings + '&cht=s&chxt=x,y&chxr=0,' + minX + ',' + maxX + '|1,' + minval + ',' + maxval + '&chd=t:' + profChart.join("|");
+ //gChart.innerHTML = '<iframe src="urlJump.html?img=' + escape(profChartUrl) + '" style="width:315px;height:270px;"></iframe>';
+}
+
+// This is where loading help text might go:
+
+function DoHelp(s, t) {
+
+ var hview = s.views.help.element;
+
+ var str = SocialCalc.Constants.s_MainHelpText;
+
+ hview.firstChild.innerHTML = str;
+
+ }
+
+</script>
+</body>
+</html>
+
diff --git a/web/jquery.js b/web/jquery.js
new file mode 100644
index 0000000..2e43a82
--- /dev/null
+++ b/web/jquery.js
@@ -0,0 +1,3408 @@
+(function(){
+/*
+ * jQuery 1.2.3 - New Wave Javascript
+ *
+ * Copyright (c) 2008 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $
+ * $Rev: 4663 $
+ */
+
+// Map over jQuery in case of overwrite
+if ( window.jQuery )
+ var _jQuery = window.jQuery;
+
+var jQuery = window.jQuery = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.prototype.init( selector, context );
+};
+
+// Map over the $ in case of overwrite
+if ( window.$ )
+ var _$ = window.$;
+
+// Map the jQuery namespace to the '$' one
+window.$ = jQuery;
+
+// A simple way to check for HTML strings or ID strings
+// (both of which we optimize for)
+var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;
+
+// Is it a simple selector
+var isSimple = /^.[^:#\[\.]*$/;
+
+jQuery.fn = jQuery.prototype = {
+ init: function( selector, context ) {
+ // Make sure that a selection was provided
+ selector = selector || document;
+
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this[0] = selector;
+ this.length = 1;
+ return this;
+
+ // Handle HTML strings
+ } else if ( typeof selector == "string" ) {
+ // Are we dealing with HTML string or an ID?
+ var match = quickExpr.exec( selector );
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] )
+ selector = jQuery.clean( [ match[1] ], context );
+
+ // HANDLE: $("#id")
+ else {
+ var elem = document.getElementById( match[3] );
+
+ // Make sure an element was located
+ if ( elem )
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id != match[3] )
+ return jQuery().find( selector );
+
+ // Otherwise, we inject the element directly into the jQuery object
+ else {
+ this[0] = elem;
+ this.length = 1;
+ return this;
+ }
+
+ else
+ selector = [];
+ }
+
+ // HANDLE: $(expr, [context])
+ // (which is just equivalent to: $(content).find(expr)
+ } else
+ return new jQuery( context ).find( selector );
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) )
+ return new jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
+
+ return this.setArray(
+ // HANDLE: $(array)
+ selector.constructor == Array && selector ||
+
+ // HANDLE: $(arraylike)
+ // Watch for when an array-like object, contains DOM nodes, is passed in as the selector
+ (selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) ||
+
+ // HANDLE: $(*)
+ [ selector ] );
+ },
+
+ // The current version of jQuery being used
+ jquery: "1.2.3",
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ return this.length;
+ },
+
+ // The number of elements contained in the matched element set
+ length: 0,
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num == undefined ?
+
+ // Return a 'clean' array
+ jQuery.makeArray( this ) :
+
+ // Return just the object
+ this[ num ];
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems ) {
+ // Build a new jQuery matched element set
+ var ret = jQuery( elems );
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Force the current matched set of elements to become
+ // the specified array of elements (destroying the stack in the process)
+ // You should use pushStack() in order to do this, but maintain the stack
+ setArray: function( elems ) {
+ // Resetting the length to 0, then using the native Array push
+ // is a super-fast way to populate an object with array-like properties
+ this.length = 0;
+ Array.prototype.push.apply( this, elems );
+
+ return this;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+ var ret = -1;
+
+ // Locate the position of the desired element
+ this.each(function(i){
+ if ( this == elem )
+ ret = i;
+ });
+
+ return ret;
+ },
+
+ attr: function( name, value, type ) {
+ var options = name;
+
+ // Look for the case where we're accessing a style value
+ if ( name.constructor == String )
+ if ( value == undefined )
+ return this.length && jQuery[ type || "attr" ]( this[0], name ) || undefined;
+
+ else {
+ options = {};
+ options[ name ] = value;
+ }
+
+ // Check to see if we're setting style values
+ return this.each(function(i){
+ // Set all the styles
+ for ( name in options )
+ jQuery.attr(
+ type ?
+ this.style :
+ this,
+ name, jQuery.prop( this, options[ name ], type, i, name )
+ );
+ });
+ },
+
+ css: function( key, value ) {
+ // ignore negative width and height values
+ if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
+ value = undefined;
+ return this.attr( key, value, "curCSS" );
+ },
+
+ text: function( text ) {
+ if ( typeof text != "object" && text != null )
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+
+ var ret = "";
+
+ jQuery.each( text || this, function(){
+ jQuery.each( this.childNodes, function(){
+ if ( this.nodeType != 8 )
+ ret += this.nodeType != 1 ?
+ this.nodeValue :
+ jQuery.fn.text( [ this ] );
+ });
+ });
+
+ return ret;
+ },
+
+ wrapAll: function( html ) {
+ if ( this[0] )
+ // The elements to wrap the target around
+ jQuery( html, this[0].ownerDocument )
+ .clone()
+ .insertBefore( this[0] )
+ .map(function(){
+ var elem = this;
+
+ while ( elem.firstChild )
+ elem = elem.firstChild;
+
+ return elem;
+ })
+ .append(this);
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ return this.each(function(){
+ jQuery( this ).contents().wrapAll( html );
+ });
+ },
+
+ wrap: function( html ) {
+ return this.each(function(){
+ jQuery( this ).wrapAll( html );
+ });
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, false, function(elem){
+ if (this.nodeType == 1)
+ this.appendChild( elem );
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, true, function(elem){
+ if (this.nodeType == 1)
+ this.insertBefore( elem, this.firstChild );
+ });
+ },
+
+ before: function() {
+ return this.domManip(arguments, false, false, function(elem){
+ this.parentNode.insertBefore( elem, this );
+ });
+ },
+
+ after: function() {
+ return this.domManip(arguments, false, true, function(elem){
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ });
+ },
+
+ end: function() {
+ return this.prevObject || jQuery( [] );
+ },
+
+ find: function( selector ) {
+ var elems = jQuery.map(this, function(elem){
+ return jQuery.find( selector, elem );
+ });
+
+ return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
+ jQuery.unique( elems ) :
+ elems );
+ },
+
+ clone: function( events ) {
+ // Do the clone
+ var ret = this.map(function(){
+ if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
+ // IE copies events bound via attachEvent when
+ // using cloneNode. Calling detachEvent on the
+ // clone will also remove the events from the orignal
+ // In order to get around this, we use innerHTML.
+ // Unfortunately, this means some modifications to
+ // attributes in IE that are actually only stored
+ // as properties will not be copied (such as the
+ // the name attribute on an input).
+ var clone = this.cloneNode(true),
+ container = document.createElement("div");
+ container.appendChild(clone);
+ return jQuery.clean([container.innerHTML])[0];
+ } else
+ return this.cloneNode(true);
+ });
+
+ // Need to set the expando to null on the cloned set if it exists
+ // removeData doesn't work here, IE removes it from the original as well
+ // this is primarily for IE but the data expando shouldn't be copied over in any browser
+ var clone = ret.find("*").andSelf().each(function(){
+ if ( this[ expando ] != undefined )
+ this[ expando ] = null;
+ });
+
+ // Copy the events from the original to the clone
+ if ( events === true )
+ this.find("*").andSelf().each(function(i){
+ if (this.nodeType == 3)
+ return;
+ var events = jQuery.data( this, "events" );
+
+ for ( var type in events )
+ for ( var handler in events[ type ] )
+ jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
+ });
+
+ // Return the cloned set
+ return ret;
+ },
+
+ filter: function( selector ) {
+ return this.pushStack(
+ jQuery.isFunction( selector ) &&
+ jQuery.grep(this, function(elem, i){
+ return selector.call( elem, i );
+ }) ||
+
+ jQuery.multiFilter( selector, this ) );
+ },
+
+ not: function( selector ) {
+ if ( selector.constructor == String )
+ // test special case where just one selector is passed in
+ if ( isSimple.test( selector ) )
+ return this.pushStack( jQuery.multiFilter( selector, this, true ) );
+ else
+ selector = jQuery.multiFilter( selector, this );
+
+ var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
+ return this.filter(function() {
+ return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
+ });
+ },
+
+ add: function( selector ) {
+ return !selector ? this : this.pushStack( jQuery.merge(
+ this.get(),
+ selector.constructor == String ?
+ jQuery( selector ).get() :
+ selector.length != undefined && (!selector.nodeName || jQuery.nodeName(selector, "form")) ?
+ selector : [selector] ) );
+ },
+
+ is: function( selector ) {
+ return selector ?
+ jQuery.multiFilter( selector, this ).length > 0 :
+ false;
+ },
+
+ hasClass: function( selector ) {
+ return this.is( "." + selector );
+ },
+
+ val: function( value ) {
+ if ( value == undefined ) {
+
+ if ( this.length ) {
+ var elem = this[0];
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName( elem, "select" ) ) {
+ var index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type == "select-one";
+
+ // Nothing was selected
+ if ( index < 0 )
+ return null;
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[ i ];
+
+ if ( option.selected ) {
+ // Get the specifc value for the option
+ value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
+
+ // We don't need an array for one selects
+ if ( one )
+ return value;
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ return values;
+
+ // Everything else, we just grab the value
+ } else
+ return (this[0].value || "").replace(/\r/g, "");
+
+ }
+
+ return undefined;
+ }
+
+ return this.each(function(){
+ if ( this.nodeType != 1 )
+ return;
+
+ if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
+ this.checked = (jQuery.inArray(this.value, value) >= 0 ||
+ jQuery.inArray(this.name, value) >= 0);
+
+ else if ( jQuery.nodeName( this, "select" ) ) {
+ var values = value.constructor == Array ?
+ value :
+ [ value ];
+
+ jQuery( "option", this ).each(function(){
+ this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
+ jQuery.inArray( this.text, values ) >= 0);
+ });
+
+ if ( !values.length )
+ this.selectedIndex = -1;
+
+ } else
+ this.value = value;
+ });
+ },
+
+ html: function( value ) {
+ return value == undefined ?
+ (this.length ?
+ this[0].innerHTML :
+ null) :
+ this.empty().append( value );
+ },
+
+ replaceWith: function( value ) {
+ return this.after( value ).remove();
+ },
+
+ eq: function( i ) {
+ return this.slice( i, i + 1 );
+ },
+
+ slice: function() {
+ return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function(elem, i){
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ },
+
+ data: function( key, value ){
+ var parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if ( value == null ) {
+ var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+ if ( data == undefined && this.length )
+ data = jQuery.data( this[0], key );
+
+ return data == null && parts[1] ?
+ this.data( parts[0] ) :
+ data;
+ } else
+ return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
+ jQuery.data( this, key, value );
+ });
+ },
+
+ removeData: function( key ){
+ return this.each(function(){
+ jQuery.removeData( this, key );
+ });
+ },
+
+ domManip: function( args, table, reverse, callback ) {
+ var clone = this.length > 1, elems;
+
+ return this.each(function(){
+ if ( !elems ) {
+ elems = jQuery.clean( args, this.ownerDocument );
+
+ if ( reverse )
+ elems.reverse();
+ }
+
+ var obj = this;
+
+ if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
+ obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
+
+ var scripts = jQuery( [] );
+
+ jQuery.each(elems, function(){
+ var elem = clone ?
+ jQuery( this ).clone( true )[0] :
+ this;
+
+ // execute all scripts after the elements have been injected
+ if ( jQuery.nodeName( elem, "script" ) ) {
+ scripts = scripts.add( elem );
+ } else {
+ // Remove any inner scripts for later evaluation
+ if ( elem.nodeType == 1 )
+ scripts = scripts.add( jQuery( "script", elem ).remove() );
+
+ // Inject the elements into the document
+ callback.call( obj, elem );
+ }
+ });
+
+ scripts.each( evalScript );
+ });
+ }
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.prototype.init.prototype = jQuery.prototype;
+
+function evalScript( i, elem ) {
+ if ( elem.src )
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+
+ else
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+
+ if ( elem.parentNode )
+ elem.parentNode.removeChild( elem );
+}
+
+jQuery.extend = jQuery.fn.extend = function() {
+ // copy reference to target object
+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
+
+ // Handle a deep copy situation
+ if ( target.constructor == Boolean ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target != "object" && typeof target != "function" )
+ target = {};
+
+ // extend jQuery itself if only one argument is passed
+ if ( length == 1 ) {
+ target = this;
+ i = 0;
+ }
+
+ for ( ; i < length; i++ )
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null )
+ // Extend the base object
+ for ( var name in options ) {
+ // Prevent never-ending loop
+ if ( target === options[ name ] )
+ continue;
+
+ // Recurse if we're merging object values
+ if ( deep && options[ name ] && typeof options[ name ] == "object" && target[ name ] && !options[ name ].nodeType )
+ target[ name ] = jQuery.extend( target[ name ], options[ name ] );
+
+ // Don't bring in undefined values
+ else if ( options[ name ] != undefined )
+ target[ name ] = options[ name ];
+
+ }
+
+ // Return the modified object
+ return target;
+};
+
+var expando = "jQuery" + (new Date()).getTime(), uuid = 0, windowData = {};
+
+// exclude the following css properties to add px
+var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i;
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ window.$ = _$;
+
+ if ( deep )
+ window.jQuery = _jQuery;
+
+ return jQuery;
+ },
+
+ // See test/unit/core.js for details concerning this function.
+ isFunction: function( fn ) {
+ return !!fn && typeof fn != "string" && !fn.nodeName &&
+ fn.constructor != Array && /function/i.test( fn + "" );
+ },
+
+ // check if an element is in a (or is an) XML document
+ isXMLDoc: function( elem ) {
+ return elem.documentElement && !elem.body ||
+ elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
+ },
+
+ // Evalulates a script in a global context
+ globalEval: function( data ) {
+ data = jQuery.trim( data );
+
+ if ( data ) {
+ // Inspired by code by Andrea Giammarchi
+ // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+ var head = document.getElementsByTagName("head")[0] || document.documentElement,
+ script = document.createElement("script");
+
+ script.type = "text/javascript";
+ if ( jQuery.browser.msie )
+ script.text = data;
+ else
+ script.appendChild( document.createTextNode( data ) );
+
+ head.appendChild( script );
+ head.removeChild( script );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
+ },
+
+ cache: {},
+
+ data: function( elem, name, data ) {
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ];
+
+ // Compute a unique ID for the element
+ if ( !id )
+ id = elem[ expando ] = ++uuid;
+
+ // Only generate the data cache if we're
+ // trying to access or manipulate it
+ if ( name && !jQuery.cache[ id ] )
+ jQuery.cache[ id ] = {};
+
+ // Prevent overriding the named cache with undefined values
+ if ( data != undefined )
+ jQuery.cache[ id ][ name ] = data;
+
+ // Return the named cache data, or the ID for the element
+ return name ?
+ jQuery.cache[ id ][ name ] :
+ id;
+ },
+
+ removeData: function( elem, name ) {
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ];
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( jQuery.cache[ id ] ) {
+ // Remove the section of cache data
+ delete jQuery.cache[ id ][ name ];
+
+ // If we've removed all the data, remove the element's cache
+ name = "";
+
+ for ( name in jQuery.cache[ id ] )
+ break;
+
+ if ( !name )
+ jQuery.removeData( elem );
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ // Clean up the element expando
+ try {
+ delete elem[ expando ];
+ } catch(e){
+ // IE has trouble directly removing the expando
+ // but it's ok with using removeAttribute
+ if ( elem.removeAttribute )
+ elem.removeAttribute( expando );
+ }
+
+ // Completely remove the data cache
+ delete jQuery.cache[ id ];
+ }
+ },
+
+ // args is for internal usage only
+ each: function( object, callback, args ) {
+ if ( args ) {
+ if ( object.length == undefined ) {
+ for ( var name in object )
+ if ( callback.apply( object[ name ], args ) === false )
+ break;
+ } else
+ for ( var i = 0, length = object.length; i < length; i++ )
+ if ( callback.apply( object[ i ], args ) === false )
+ break;
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( object.length == undefined ) {
+ for ( var name in object )
+ if ( callback.call( object[ name ], name, object[ name ] ) === false )
+ break;
+ } else
+ for ( var i = 0, length = object.length, value = object[0];
+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
+ }
+
+ return object;
+ },
+
+ prop: function( elem, value, type, i, name ) {
+ // Handle executable functions
+ if ( jQuery.isFunction( value ) )
+ value = value.call( elem, i );
+
+ // Handle passing in a number to a CSS property
+ return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
+ value + "px" :
+ value;
+ },
+
+ className: {
+ // internal only, use addClass("class")
+ add: function( elem, classNames ) {
+ jQuery.each((classNames || "").split(/\s+/), function(i, className){
+ if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
+ elem.className += (elem.className ? " " : "") + className;
+ });
+ },
+
+ // internal only, use removeClass("class")
+ remove: function( elem, classNames ) {
+ if (elem.nodeType == 1)
+ elem.className = classNames != undefined ?
+ jQuery.grep(elem.className.split(/\s+/), function(className){
+ return !jQuery.className.has( classNames, className );
+ }).join(" ") :
+ "";
+ },
+
+ // internal only, use is(".class")
+ has: function( elem, className ) {
+ return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
+ }
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ var old = {};
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ callback.call( elem );
+
+ // Revert the old values
+ for ( var name in options )
+ elem.style[ name ] = old[ name ];
+ },
+
+ css: function( elem, name, force ) {
+ if ( name == "width" || name == "height" ) {
+ var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
+
+ function getWH() {
+ val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
+ var padding = 0, border = 0;
+ jQuery.each( which, function() {
+ padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
+ border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
+ });
+ val -= Math.round(padding + border);
+ }
+
+ if ( jQuery(elem).is(":visible") )
+ getWH();
+ else
+ jQuery.swap( elem, props, getWH );
+
+ return Math.max(0, val);
+ }
+
+ return jQuery.curCSS( elem, name, force );
+ },
+
+ curCSS: function( elem, name, force ) {
+ var ret;
+
+ // A helper method for determining if an element's values are broken
+ function color( elem ) {
+ if ( !jQuery.browser.safari )
+ return false;
+
+ var ret = document.defaultView.getComputedStyle( elem, null );
+ return !ret || ret.getPropertyValue("color") == "";
+ }
+
+ // We need to handle opacity special in IE
+ if ( name == "opacity" && jQuery.browser.msie ) {
+ ret = jQuery.attr( elem.style, "opacity" );
+
+ return ret == "" ?
+ "1" :
+ ret;
+ }
+ // Opera sometimes will give the wrong display answer, this fixes it, see #2037
+ if ( jQuery.browser.opera && name == "display" ) {
+ var save = elem.style.outline;
+ elem.style.outline = "0 solid black";
+ elem.style.outline = save;
+ }
+
+ // Make sure we're using the right name for getting the float value
+ if ( name.match( /float/i ) )
+ name = styleFloat;
+
+ if ( !force && elem.style && elem.style[ name ] )
+ ret = elem.style[ name ];
+
+ else if ( document.defaultView && document.defaultView.getComputedStyle ) {
+
+ // Only "float" is needed here
+ if ( name.match( /float/i ) )
+ name = "float";
+
+ name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
+
+ var getComputedStyle = document.defaultView.getComputedStyle( elem, null );
+
+ if ( getComputedStyle && !color( elem ) )
+ ret = getComputedStyle.getPropertyValue( name );
+
+ // If the element isn't reporting its values properly in Safari
+ // then some display: none elements are involved
+ else {
+ var swap = [], stack = [];
+
+ // Locate all of the parent display: none elements
+ for ( var a = elem; a && color(a); a = a.parentNode )
+ stack.unshift(a);
+
+ // Go through and make them visible, but in reverse
+ // (It would be better if we knew the exact display type that they had)
+ for ( var i = 0; i < stack.length; i++ )
+ if ( color( stack[ i ] ) ) {
+ swap[ i ] = stack[ i ].style.display;
+ stack[ i ].style.display = "block";
+ }
+
+ // Since we flip the display style, we have to handle that
+ // one special, otherwise get the value
+ ret = name == "display" && swap[ stack.length - 1 ] != null ?
+ "none" :
+ ( getComputedStyle && getComputedStyle.getPropertyValue( name ) ) || "";
+
+ // Finally, revert the display styles back
+ for ( var i = 0; i < swap.length; i++ )
+ if ( swap[ i ] != null )
+ stack[ i ].style.display = swap[ i ];
+ }
+
+ // We should always get a number back from opacity
+ if ( name == "opacity" && ret == "" )
+ ret = "1";
+
+ } else if ( elem.currentStyle ) {
+ var camelCase = name.replace(/\-(\w)/g, function(all, letter){
+ return letter.toUpperCase();
+ });
+
+ ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
+ // Remember the original values
+ var style = elem.style.left, runtimeStyle = elem.runtimeStyle.left;
+
+ // Put in the new values to get a computed value out
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ elem.style.left = ret || 0;
+ ret = elem.style.pixelLeft + "px";
+
+ // Revert the changed values
+ elem.style.left = style;
+ elem.runtimeStyle.left = runtimeStyle;
+ }
+ }
+
+ return ret;
+ },
+
+ clean: function( elems, context ) {
+ var ret = [];
+ context = context || document;
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if (typeof context.createElement == 'undefined')
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+
+ jQuery.each(elems, function(i, elem){
+ if ( !elem )
+ return;
+
+ if ( elem.constructor == Number )
+ elem = elem.toString();
+
+ // Convert html string into DOM nodes
+ if ( typeof elem == "string" ) {
+ // Fix "XHTML"-style tags in all browsers
+ elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
+ return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
+ all :
+ front + "></" + tag + ">";
+ });
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
+
+ var wrap =
+ // option or optgroup
+ !tags.indexOf("<opt") &&
+ [ 1, "<select multiple='multiple'>", "</select>" ] ||
+
+ !tags.indexOf("<leg") &&
+ [ 1, "<fieldset>", "</fieldset>" ] ||
+
+ tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
+ [ 1, "<table>", "</table>" ] ||
+
+ !tags.indexOf("<tr") &&
+ [ 2, "<table><tbody>", "</tbody></table>" ] ||
+
+ // <thead> matched above
+ (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
+ [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
+
+ !tags.indexOf("<col") &&
+ [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
+
+ // IE can't serialize <link> and <script> tags normally
+ jQuery.browser.msie &&
+ [ 1, "div<div>", "</div>" ] ||
+
+ [ 0, "", "" ];
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + elem + wrap[2];
+
+ // Move to the right depth
+ while ( wrap[0]-- )
+ div = div.lastChild;
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( jQuery.browser.msie ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
+ div.firstChild && div.firstChild.childNodes :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
+ div.childNodes :
+ [];
+
+ for ( var j = tbody.length - 1; j >= 0 ; --j )
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( /^\s/.test( elem ) )
+ div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
+
+ }
+
+ elem = jQuery.makeArray( div.childNodes );
+ }
+
+ if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
+ return;
+
+ if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
+ ret.push( elem );
+
+ else
+ ret = jQuery.merge( ret, elem );
+
+ });
+
+ return ret;
+ },
+
+ attr: function( elem, name, value ) {
+ // don't set attributes on text and comment nodes
+ if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
+ return undefined;
+
+ var fix = jQuery.isXMLDoc( elem ) ?
+ {} :
+ jQuery.props;
+
+ // Safari mis-reports the default selected property of a hidden option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name == "selected" && jQuery.browser.safari )
+ elem.parentNode.selectedIndex;
+
+ // Certain attributes only work when accessed via the old DOM 0 way
+ if ( fix[ name ] ) {
+ if ( value != undefined )
+ elem[ fix[ name ] ] = value;
+
+ return elem[ fix[ name ] ];
+
+ } else if ( jQuery.browser.msie && name == "style" )
+ return jQuery.attr( elem.style, "cssText", value );
+
+ else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName( elem, "form" ) && (name == "action" || name == "method") )
+ return elem.getAttributeNode( name ).nodeValue;
+
+ // IE elem.getAttribute passes even for style
+ else if ( elem.tagName ) {
+
+ if ( value != undefined ) {
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
+ throw "type property can't be changed";
+
+ // convert the value to a string (all browsers do this but IE) see #1070
+ elem.setAttribute( name, "" + value );
+ }
+
+ if ( jQuery.browser.msie && /href|src/.test( name ) && !jQuery.isXMLDoc( elem ) )
+ return elem.getAttribute( name, 2 );
+
+ return elem.getAttribute( name );
+
+ // elem is actually elem.style ... set the style
+ } else {
+ // IE actually uses filters for opacity
+ if ( name == "opacity" && jQuery.browser.msie ) {
+ if ( value != undefined ) {
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ elem.zoom = 1;
+
+ // Set the alpha filter to set the opacity
+ elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
+ (parseFloat( value ).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
+ }
+
+ return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
+ (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() :
+ "";
+ }
+
+ name = name.replace(/-([a-z])/ig, function(all, letter){
+ return letter.toUpperCase();
+ });
+
+ if ( value != undefined )
+ elem[ name ] = value;
+
+ return elem[ name ];
+ }
+ },
+
+ trim: function( text ) {
+ return (text || "").replace( /^\s+|\s+$/g, "" );
+ },
+
+ makeArray: function( array ) {
+ var ret = [];
+
+ // Need to use typeof to fight Safari childNodes crashes
+ if ( typeof array != "array" )
+ for ( var i = 0, length = array.length; i < length; i++ )
+ ret.push( array[ i ] );
+ else
+ ret = array.slice( 0 );
+
+ return ret;
+ },
+
+ inArray: function( elem, array ) {
+ for ( var i = 0, length = array.length; i < length; i++ )
+ if ( array[ i ] == elem )
+ return i;
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ // We have to loop this way because IE & Opera overwrite the length
+ // expando of getElementsByTagName
+
+ // Also, we need to make sure that the correct elements are being returned
+ // (IE returns comment nodes in a '*' query)
+ if ( jQuery.browser.msie ) {
+ for ( var i = 0; second[ i ]; i++ )
+ if ( second[ i ].nodeType != 8 )
+ first.push( second[ i ] );
+
+ } else
+ for ( var i = 0; second[ i ]; i++ )
+ first.push( second[ i ] );
+
+ return first;
+ },
+
+ unique: function( array ) {
+ var ret = [], done = {};
+
+ try {
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ var id = jQuery.data( array[ i ] );
+
+ if ( !done[ id ] ) {
+ done[ id ] = true;
+ ret.push( array[ i ] );
+ }
+ }
+
+ } catch( e ) {
+ ret = array;
+ }
+
+ return ret;
+ },
+
+ grep: function( elems, callback, inv ) {
+ var ret = [];
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ )
+ if ( !inv && callback( elems[ i ], i ) || inv && !callback( elems[ i ], i ) )
+ ret.push( elems[ i ] );
+
+ return ret;
+ },
+
+ map: function( elems, callback ) {
+ var ret = [];
+
+ // Go through the array, translating each of the items to their
+ // new value (or values).
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ var value = callback( elems[ i ], i );
+
+ if ( value !== null && value != undefined ) {
+ if ( value.constructor != Array )
+ value = [ value ];
+
+ ret = ret.concat( value );
+ }
+ }
+
+ return ret;
+ }
+});
+
+var userAgent = navigator.userAgent.toLowerCase();
+
+// Figure out what browser is being used
+jQuery.browser = {
+ version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
+ safari: /webkit/.test( userAgent ),
+ opera: /opera/.test( userAgent ),
+ msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
+ mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
+};
+
+var styleFloat = jQuery.browser.msie ?
+ "styleFloat" :
+ "cssFloat";
+
+jQuery.extend({
+ // Check to see if the W3C box model is being used
+ boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
+
+ props: {
+ "for": "htmlFor",
+ "class": "className",
+ "float": styleFloat,
+ cssFloat: styleFloat,
+ styleFloat: styleFloat,
+ innerHTML: "innerHTML",
+ className: "className",
+ value: "value",
+ disabled: "disabled",
+ checked: "checked",
+ readonly: "readOnly",
+ selected: "selected",
+ maxlength: "maxLength",
+ selectedIndex: "selectedIndex",
+ defaultValue: "defaultValue",
+ tagName: "tagName",
+ nodeName: "nodeName"
+ }
+});
+
+jQuery.each({
+ parent: function(elem){return elem.parentNode;},
+ parents: function(elem){return jQuery.dir(elem,"parentNode");},
+ next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
+ prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
+ nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
+ prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
+ siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
+ children: function(elem){return jQuery.sibling(elem.firstChild);},
+ contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
+}, function(name, fn){
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = jQuery.map( this, fn );
+
+ if ( selector && typeof selector == "string" )
+ ret = jQuery.multiFilter( selector, ret );
+
+ return this.pushStack( jQuery.unique( ret ) );
+ };
+});
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function(name, original){
+ jQuery.fn[ name ] = function() {
+ var args = arguments;
+
+ return this.each(function(){
+ for ( var i = 0, length = args.length; i < length; i++ )
+ jQuery( args[ i ] )[ original ]( this );
+ });
+ };
+});
+
+jQuery.each({
+ removeAttr: function( name ) {
+ jQuery.attr( this, name, "" );
+ if (this.nodeType == 1)
+ this.removeAttribute( name );
+ },
+
+ addClass: function( classNames ) {
+ jQuery.className.add( this, classNames );
+ },
+
+ removeClass: function( classNames ) {
+ jQuery.className.remove( this, classNames );
+ },
+
+ toggleClass: function( classNames ) {
+ jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
+ },
+
+ remove: function( selector ) {
+ if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
+ // Prevent memory leaks
+ jQuery( "*", this ).add(this).each(function(){
+ jQuery.event.remove(this);
+ jQuery.removeData(this);
+ });
+ if (this.parentNode)
+ this.parentNode.removeChild( this );
+ }
+ },
+
+ empty: function() {
+ // Remove element nodes and prevent memory leaks
+ jQuery( ">*", this ).remove();
+
+ // Remove any remaining nodes
+ while ( this.firstChild )
+ this.removeChild( this.firstChild );
+ }
+}, function(name, fn){
+ jQuery.fn[ name ] = function(){
+ return this.each( fn, arguments );
+ };
+});
+
+jQuery.each([ "Height", "Width" ], function(i, name){
+ var type = name.toLowerCase();
+
+ jQuery.fn[ type ] = function( size ) {
+ // Get window width or height
+ return this[0] == window ?
+ // Opera reports document.body.client[Width/Height] properly in both quirks and standards
+ jQuery.browser.opera && document.body[ "client" + name ] ||
+
+ // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
+ jQuery.browser.safari && window[ "inner" + name ] ||
+
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
+
+ // Get document width or height
+ this[0] == document ?
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ Math.max(
+ Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
+ Math.max(document.body["offset" + name], document.documentElement["offset" + name])
+ ) :
+
+ // Get or set width or height on the element
+ size == undefined ?
+ // Get width or height on the element
+ (this.length ? jQuery.css( this[0], type ) : null) :
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ this.css( type, size.constructor == String ? size : size + "px" );
+ };
+});
+
+var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
+ "(?:[\\w*_-]|\\\\.)" :
+ "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
+ quickChild = new RegExp("^>\\s*(" + chars + "+)"),
+ quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
+ quickClass = new RegExp("^([#.]?)(" + chars + "*)");
+
+jQuery.extend({
+ expr: {
+ "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
+ "#": function(a,i,m){return a.getAttribute("id")==m[2];},
+ ":": {
+ // Position Checks
+ lt: function(a,i,m){return i<m[3]-0;},
+ gt: function(a,i,m){return i>m[3]-0;},
+ nth: function(a,i,m){return m[3]-0==i;},
+ eq: function(a,i,m){return m[3]-0==i;},
+ first: function(a,i){return i==0;},
+ last: function(a,i,m,r){return i==r.length-1;},
+ even: function(a,i){return i%2==0;},
+ odd: function(a,i){return i%2;},
+
+ // Child Checks
+ "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
+ "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
+ "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
+
+ // Parent Checks
+ parent: function(a){return a.firstChild;},
+ empty: function(a){return !a.firstChild;},
+
+ // Text Check
+ contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
+
+ // Visibility
+ visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
+ hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
+
+ // Form attributes
+ enabled: function(a){return !a.disabled;},
+ disabled: function(a){return a.disabled;},
+ checked: function(a){return a.checked;},
+ selected: function(a){return a.selected||jQuery.attr(a,"selected");},
+
+ // Form elements
+ text: function(a){return "text"==a.type;},
+ radio: function(a){return "radio"==a.type;},
+ checkbox: function(a){return "checkbox"==a.type;},
+ file: function(a){return "file"==a.type;},
+ password: function(a){return "password"==a.type;},
+ submit: function(a){return "submit"==a.type;},
+ image: function(a){return "image"==a.type;},
+ reset: function(a){return "reset"==a.type;},
+ button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
+ input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},
+
+ // :has()
+ has: function(a,i,m){return jQuery.find(m[3],a).length;},
+
+ // :header
+ header: function(a){return /h\d/i.test(a.nodeName);},
+
+ // :animated
+ animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
+ }
+ },
+
+ // The regular expressions that power the parsing engine
+ parse: [
+ // Match: [@value='test'], [@foo]
+ /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
+
+ // Match: :contains('foo')
+ /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
+
+ // Match: :even, :last-chlid, #id, .class
+ new RegExp("^([:.#]*)(" + chars + "+)")
+ ],
+
+ multiFilter: function( expr, elems, not ) {
+ var old, cur = [];
+
+ while ( expr && expr != old ) {
+ old = expr;
+ var f = jQuery.filter( expr, elems, not );
+ expr = f.t.replace(/^\s*,\s*/, "" );
+ cur = not ? elems = f.r : jQuery.merge( cur, f.r );
+ }
+
+ return cur;
+ },
+
+ find: function( t, context ) {
+ // Quickly handle non-string expressions
+ if ( typeof t != "string" )
+ return [ t ];
+
+ // check to make sure context is a DOM element or a document
+ if ( context && context.nodeType != 1 && context.nodeType != 9)
+ return [ ];
+
+ // Set the correct context (if none is provided)
+ context = context || document;
+
+ // Initialize the search
+ var ret = [context], done = [], last, nodeName;
+
+ // Continue while a selector expression exists, and while
+ // we're no longer looping upon ourselves
+ while ( t && last != t ) {
+ var r = [];
+ last = t;
+
+ t = jQuery.trim(t);
+
+ var foundToken = false;
+
+ // An attempt at speeding up child selectors that
+ // point to a specific element tag
+ var re = quickChild;
+ var m = re.exec(t);
+
+ if ( m ) {
+ nodeName = m[1].toUpperCase();
+
+ // Perform our own iteration and filter
+ for ( var i = 0; ret[i]; i++ )
+ for ( var c = ret[i].firstChild; c; c = c.nextSibling )
+ if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
+ r.push( c );
+
+ ret = r;
+ t = t.replace( re, "" );
+ if ( t.indexOf(" ") == 0 ) continue;
+ foundToken = true;
+ } else {
+ re = /^([>+~])\s*(\w*)/i;
+
+ if ( (m = re.exec(t)) != null ) {
+ r = [];
+
+ var merge = {};
+ nodeName = m[2].toUpperCase();
+ m = m[1];
+
+ for ( var j = 0, rl = ret.length; j < rl; j++ ) {
+ var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
+ for ( ; n; n = n.nextSibling )
+ if ( n.nodeType == 1 ) {
+ var id = jQuery.data(n);
+
+ if ( m == "~" && merge[id] ) break;
+
+ if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
+ if ( m == "~" ) merge[id] = true;
+ r.push( n );
+ }
+
+ if ( m == "+" ) break;
+ }
+ }
+
+ ret = r;
+
+ // And remove the token
+ t = jQuery.trim( t.replace( re, "" ) );
+ foundToken = true;
+ }
+ }
+
+ // See if there's still an expression, and that we haven't already
+ // matched a token
+ if ( t && !foundToken ) {
+ // Handle multiple expressions
+ if ( !t.indexOf(",") ) {
+ // Clean the result set
+ if ( context == ret[0] ) ret.shift();
+
+ // Merge the result sets
+ done = jQuery.merge( done, ret );
+
+ // Reset the context
+ r = ret = [context];
+
+ // Touch up the selector string
+ t = " " + t.substr(1,t.length);
+
+ } else {
+ // Optimize for the case nodeName#idName
+ var re2 = quickID;
+ var m = re2.exec(t);
+
+ // Re-organize the results, so that they're consistent
+ if ( m ) {
+ m = [ 0, m[2], m[3], m[1] ];
+
+ } else {
+ // Otherwise, do a traditional filter check for
+ // ID, class, and element selectors
+ re2 = quickClass;
+ m = re2.exec(t);
+ }
+
+ m[2] = m[2].replace(/\\/g, "");
+
+ var elem = ret[ret.length-1];
+
+ // Try to do a global search by ID, where we can
+ if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
+ // Optimization for HTML document case
+ var oid = elem.getElementById(m[2]);
+
+ // Do a quick check for the existence of the actual ID attribute
+ // to avoid selecting by the name attribute in IE
+ // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
+ if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
+ oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
+
+ // Do a quick check for node name (where applicable) so
+ // that div#foo searches will be really fast
+ ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
+ } else {
+ // We need to find all descendant elements
+ for ( var i = 0; ret[i]; i++ ) {
+ // Grab the tag name being searched for
+ var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
+
+ // Handle IE7 being really dumb about <object>s
+ if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
+ tag = "param";
+
+ r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
+ }
+
+ // It's faster to filter by class and be done with it
+ if ( m[1] == "." )
+ r = jQuery.classFilter( r, m[2] );
+
+ // Same with ID filtering
+ if ( m[1] == "#" ) {
+ var tmp = [];
+
+ // Try to find the element with the ID
+ for ( var i = 0; r[i]; i++ )
+ if ( r[i].getAttribute("id") == m[2] ) {
+ tmp = [ r[i] ];
+ break;
+ }
+
+ r = tmp;
+ }
+
+ ret = r;
+ }
+
+ t = t.replace( re2, "" );
+ }
+
+ }
+
+ // If a selector string still exists
+ if ( t ) {
+ // Attempt to filter it
+ var val = jQuery.filter(t,r);
+ ret = r = val.r;
+ t = jQuery.trim(val.t);
+ }
+ }
+
+ // An error occurred with the selector;
+ // just return an empty set instead
+ if ( t )
+ ret = [];
+
+ // Remove the root context
+ if ( ret && context == ret[0] )
+ ret.shift();
+
+ // And combine the results
+ done = jQuery.merge( done, ret );
+
+ return done;
+ },
+
+ classFilter: function(r,m,not){
+ m = " " + m + " ";
+ var tmp = [];
+ for ( var i = 0; r[i]; i++ ) {
+ var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
+ if ( !not && pass || not && !pass )
+ tmp.push( r[i] );
+ }
+ return tmp;
+ },
+
+ filter: function(t,r,not) {
+ var last;
+
+ // Look for common filter expressions
+ while ( t && t != last ) {
+ last = t;
+
+ var p = jQuery.parse, m;
+
+ for ( var i = 0; p[i]; i++ ) {
+ m = p[i].exec( t );
+
+ if ( m ) {
+ // Remove what we just matched
+ t = t.substring( m[0].length );
+
+ m[2] = m[2].replace(/\\/g, "");
+ break;
+ }
+ }
+
+ if ( !m )
+ break;
+
+ // :not() is a special case that can be optimized by
+ // keeping it out of the expression list
+ if ( m[1] == ":" && m[2] == "not" )
+ // optimize if only one selector found (most common case)
+ r = isSimple.test( m[3] ) ?
+ jQuery.filter(m[3], r, true).r :
+ jQuery( r ).not( m[3] );
+
+ // We can get a big speed boost by filtering by class here
+ else if ( m[1] == "." )
+ r = jQuery.classFilter(r, m[2], not);
+
+ else if ( m[1] == "[" ) {
+ var tmp = [], type = m[3];
+
+ for ( var i = 0, rl = r.length; i < rl; i++ ) {
+ var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
+
+ if ( z == null || /href|src|selected/.test(m[2]) )
+ z = jQuery.attr(a,m[2]) || '';
+
+ if ( (type == "" && !!z ||
+ type == "=" && z == m[5] ||
+ type == "!=" && z != m[5] ||
+ type == "^=" && z && !z.indexOf(m[5]) ||
+ type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
+ (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
+ tmp.push( a );
+ }
+
+ r = tmp;
+
+ // We can get a speed boost by handling nth-child here
+ } else if ( m[1] == ":" && m[2] == "nth-child" ) {
+ var merge = {}, tmp = [],
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+ m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
+ !/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
+ // calculate the numbers (first)n+(last) including if they are negative
+ first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
+
+ // loop through all the elements left in the jQuery object
+ for ( var i = 0, rl = r.length; i < rl; i++ ) {
+ var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
+
+ if ( !merge[id] ) {
+ var c = 1;
+
+ for ( var n = parentNode.firstChild; n; n = n.nextSibling )
+ if ( n.nodeType == 1 )
+ n.nodeIndex = c++;
+
+ merge[id] = true;
+ }
+
+ var add = false;
+
+ if ( first == 0 ) {
+ if ( node.nodeIndex == last )
+ add = true;
+ } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
+ add = true;
+
+ if ( add ^ not )
+ tmp.push( node );
+ }
+
+ r = tmp;
+
+ // Otherwise, find the expression to execute
+ } else {
+ var fn = jQuery.expr[ m[1] ];
+ if ( typeof fn == "object" )
+ fn = fn[ m[2] ];
+
+ if ( typeof fn == "string" )
+ fn = eval("false||function(a,i){return " + fn + ";}");
+
+ // Execute it against the current filter
+ r = jQuery.grep( r, function(elem, i){
+ return fn(elem, i, m, r);
+ }, not );
+ }
+ }
+
+ // Return an array of filtered elements (r)
+ // and the modified expression string (t)
+ return { r: r, t: t };
+ },
+
+ dir: function( elem, dir ){
+ var matched = [];
+ var cur = elem[dir];
+ while ( cur && cur != document ) {
+ if ( cur.nodeType == 1 )
+ matched.push( cur );
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ nth: function(cur,result,dir,elem){
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] )
+ if ( cur.nodeType == 1 && ++num == result )
+ break;
+
+ return cur;
+ },
+
+ sibling: function( n, elem ) {
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType == 1 && (!elem || n != elem) )
+ r.push( n );
+ }
+
+ return r;
+ }
+});
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code orignated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function(elem, types, handler, data) {
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return;
+
+ // For whatever reason, IE has trouble passing the window object
+ // around, causing it to be cloned in the process
+ if ( jQuery.browser.msie && elem.setInterval != undefined )
+ elem = window;
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid )
+ handler.guid = this.guid++;
+
+ // if data is passed, bind to handler
+ if( data != undefined ) {
+ // Create temporary function pointer to original handler
+ var fn = handler;
+
+ // Create unique handler function, wrapped around original handler
+ handler = function() {
+ // Pass arguments and context to original handler
+ return fn.apply(this, arguments);
+ };
+
+ // Store data in unique handler
+ handler.data = data;
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ handler.guid = fn.guid;
+ }
+
+ // Init the element's event structure
+ var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
+ handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
+ // returned undefined or false
+ var val;
+
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ if ( typeof jQuery == "undefined" || jQuery.event.triggered )
+ return val;
+
+ val = jQuery.event.handle.apply(arguments.callee.elem, arguments);
+
+ return val;
+ });
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native
+ // event in IE.
+ handle.elem = elem;
+
+ // Handle multiple events seperated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ jQuery.each(types.split(/\s+/), function(index, type) {
+ // Namespaced event handlers
+ var parts = type.split(".");
+ type = parts[0];
+ handler.type = parts[1];
+
+ // Get the current list of functions bound to this event
+ var handlers = events[type];
+
+ // Init the event handler queue
+ if (!handlers) {
+ handlers = events[type] = {};
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
+ // Bind the global event handler to the element
+ if (elem.addEventListener)
+ elem.addEventListener(type, handle, false);
+ else if (elem.attachEvent)
+ elem.attachEvent("on" + type, handle);
+ }
+ }
+
+ // Add the function to the element's handler list
+ handlers[handler.guid] = handler;
+
+ // Keep track of which events have been used, for global triggering
+ jQuery.event.global[type] = true;
+ });
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ guid: 1,
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function(elem, types, handler) {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return;
+
+ var events = jQuery.data(elem, "events"), ret, index;
+
+ if ( events ) {
+ // Unbind all events for the element
+ if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
+ for ( var type in events )
+ this.remove( elem, type + (types || "") );
+ else {
+ // types is actually an event object here
+ if ( types.type ) {
+ handler = types.handler;
+ types = types.type;
+ }
+
+ // Handle multiple events seperated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ jQuery.each(types.split(/\s+/), function(index, type){
+ // Namespaced event handlers
+ var parts = type.split(".");
+ type = parts[0];
+
+ if ( events[type] ) {
+ // remove the given handler for the given type
+ if ( handler )
+ delete events[type][handler.guid];
+
+ // remove all handlers for the given type
+ else
+ for ( handler in events[type] )
+ // Handle the removal of namespaced events
+ if ( !parts[1] || events[type][handler].type == parts[1] )
+ delete events[type][handler];
+
+ // remove generic event handler if no more handlers exist
+ for ( ret in events[type] ) break;
+ if ( !ret ) {
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
+ if (elem.removeEventListener)
+ elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
+ else if (elem.detachEvent)
+ elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
+ }
+ ret = null;
+ delete events[type];
+ }
+ }
+ });
+ }
+
+ // Remove the expando if it's no longer used
+ for ( ret in events ) break;
+ if ( !ret ) {
+ var handle = jQuery.data( elem, "handle" );
+ if ( handle ) handle.elem = null;
+ jQuery.removeData( elem, "events" );
+ jQuery.removeData( elem, "handle" );
+ }
+ }
+ },
+
+ trigger: function(type, data, elem, donative, extra) {
+ // Clone the incoming data, if any
+ data = jQuery.makeArray(data || []);
+
+ if ( type.indexOf("!") >= 0 ) {
+ type = type.slice(0, -1);
+ var exclusive = true;
+ }
+
+ // Handle a global trigger
+ if ( !elem ) {
+ // Only trigger if we've ever bound an event for it
+ if ( this.global[type] )
+ jQuery("*").add([window, document]).trigger(type, data);
+
+ // Handle triggering a single element
+ } else {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return undefined;
+
+ var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
+ // Check to see if we need to provide a fake event, or not
+ event = !data[0] || !data[0].preventDefault;
+
+ // Pass along a fake event
+ if ( event )
+ data.unshift( this.fix({ type: type, target: elem }) );
+
+ // Enforce the right trigger type
+ data[0].type = type;
+ if ( exclusive )
+ data[0].exclusive = true;
+
+ // Trigger the event
+ if ( jQuery.isFunction( jQuery.data(elem, "handle") ) )
+ val = jQuery.data(elem, "handle").apply( elem, data );
+
+ // Handle triggering native .onfoo handlers
+ if ( !fn && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
+ val = false;
+
+ // Extra functions don't get the custom event object
+ if ( event )
+ data.shift();
+
+ // Handle triggering of extra function
+ if ( extra && jQuery.isFunction( extra ) ) {
+ // call the extra function and tack the current return value on the end for possible inspection
+ ret = extra.apply( elem, val == null ? data : data.concat( val ) );
+ // if anything is returned, give it precedence and have it overwrite the previous value
+ if (ret !== undefined)
+ val = ret;
+ }
+
+ // Trigger the native events (except for clicks on links)
+ if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
+ this.triggered = true;
+ try {
+ elem[ type ]();
+ // prevent IE from throwing an error for some hidden elements
+ } catch (e) {}
+ }
+
+ this.triggered = false;
+ }
+
+ return val;
+ },
+
+ handle: function(event) {
+ // returned undefined or false
+ var val;
+
+ // Empty object is for triggered events with no data
+ event = jQuery.event.fix( event || window.event || {} );
+
+ // Namespaced event handlers
+ var parts = event.type.split(".");
+ event.type = parts[0];
+
+ var handlers = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 );
+ args.unshift( event );
+
+ for ( var j in handlers ) {
+ var handler = handlers[j];
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ args[0].handler = handler;
+ args[0].data = handler.data;
+
+ // Filter the functions by class
+ if ( !parts[1] && !event.exclusive || handler.type == parts[1] ) {
+ var ret = handler.apply( this, args );
+
+ if ( val !== false )
+ val = ret;
+
+ if ( ret === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }
+
+ // Clean up added properties in IE to prevent memory leak
+ if (jQuery.browser.msie)
+ event.target = event.preventDefault = event.stopPropagation =
+ event.handler = event.data = null;
+
+ return val;
+ },
+
+ fix: function(event) {
+ // store a copy of the original event object
+ // and clone to set read-only properties
+ var originalEvent = event;
+ event = jQuery.extend({}, originalEvent);
+
+ // add preventDefault and stopPropagation since
+ // they will not work on the clone
+ event.preventDefault = function() {
+ // if preventDefault exists run it on the original event
+ if (originalEvent.preventDefault)
+ originalEvent.preventDefault();
+ // otherwise set the returnValue property of the original event to false (IE)
+ originalEvent.returnValue = false;
+ };
+ event.stopPropagation = function() {
+ // if stopPropagation exists run it on the original event
+ if (originalEvent.stopPropagation)
+ originalEvent.stopPropagation();
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ originalEvent.cancelBubble = true;
+ };
+
+ // Fix target property, if necessary
+ if ( !event.target )
+ event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+
+ // check if target is a textnode (safari)
+ if ( event.target.nodeType == 3 )
+ event.target = originalEvent.target.parentNode;
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement )
+ event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var doc = document.documentElement, body = document.body;
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
+ }
+
+ // Add which for key events
+ if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
+ event.which = event.charCode || event.keyCode;
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey )
+ event.metaKey = event.ctrlKey;
+
+ // Add which for click: 1 == left; 2 == middle; 3 == right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button )
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+
+ return event;
+ },
+
+ special: {
+ ready: {
+ setup: function() {
+ // Make sure the ready event is setup
+ bindReady();
+ return;
+ },
+
+ teardown: function() { return; }
+ },
+
+ mouseenter: {
+ setup: function() {
+ if ( jQuery.browser.msie ) return false;
+ jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
+ return true;
+ },
+
+ teardown: function() {
+ if ( jQuery.browser.msie ) return false;
+ jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
+ return true;
+ },
+
+ handler: function(event) {
+ // If we actually just moused on to a sub-element, ignore it
+ if ( withinElement(event, this) ) return true;
+ // Execute the right handlers by setting the event type to mouseenter
+ arguments[0].type = "mouseenter";
+ return jQuery.event.handle.apply(this, arguments);
+ }
+ },
+
+ mouseleave: {
+ setup: function() {
+ if ( jQuery.browser.msie ) return false;
+ jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
+ return true;
+ },
+
+ teardown: function() {
+ if ( jQuery.browser.msie ) return false;
+ jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
+ return true;
+ },
+
+ handler: function(event) {
+ // If we actually just moused on to a sub-element, ignore it
+ if ( withinElement(event, this) ) return true;
+ // Execute the right handlers by setting the event type to mouseleave
+ arguments[0].type = "mouseleave";
+ return jQuery.event.handle.apply(this, arguments);
+ }
+ }
+ }
+};
+
+jQuery.fn.extend({
+ bind: function( type, data, fn ) {
+ return type == "unload" ? this.one(type, data, fn) : this.each(function(){
+ jQuery.event.add( this, type, fn || data, fn && data );
+ });
+ },
+
+ one: function( type, data, fn ) {
+ return this.each(function(){
+ jQuery.event.add( this, type, function(event) {
+ jQuery(this).unbind(event);
+ return (fn || data).apply( this, arguments);
+ }, fn && data);
+ });
+ },
+
+ unbind: function( type, fn ) {
+ return this.each(function(){
+ jQuery.event.remove( this, type, fn );
+ });
+ },
+
+ trigger: function( type, data, fn ) {
+ return this.each(function(){
+ jQuery.event.trigger( type, data, this, true, fn );
+ });
+ },
+
+ triggerHandler: function( type, data, fn ) {
+ if ( this[0] )
+ return jQuery.event.trigger( type, data, this[0], false, fn );
+ return undefined;
+ },
+
+ toggle: function() {
+ // Save reference to arguments for access in closure
+ var args = arguments;
+
+ return this.click(function(event) {
+ // Figure out which function to execute
+ this.lastToggle = 0 == this.lastToggle ? 1 : 0;
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[this.lastToggle].apply( this, arguments ) || false;
+ });
+ },
+
+ hover: function(fnOver, fnOut) {
+ return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
+ },
+
+ ready: function(fn) {
+ // Attach the listeners
+ bindReady();
+
+ // If the DOM is already ready
+ if ( jQuery.isReady )
+ // Execute the function immediately
+ fn.call( document, jQuery );
+
+ // Otherwise, remember the function for later
+ else
+ // Add the function to the wait list
+ jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
+
+ return this;
+ }
+});
+
+jQuery.extend({
+ isReady: false,
+ readyList: [],
+ // Handle when the DOM is ready
+ ready: function() {
+ // Make sure that the DOM is not already loaded
+ if ( !jQuery.isReady ) {
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If there are functions bound, to execute
+ if ( jQuery.readyList ) {
+ // Execute all of them
+ jQuery.each( jQuery.readyList, function(){
+ this.apply( document );
+ });
+
+ // Reset the list of functions
+ jQuery.readyList = null;
+ }
+
+ // Trigger any bound ready events
+ jQuery(document).triggerHandler("ready");
+ }
+ }
+});
+
+var readyBound = false;
+
+function bindReady(){
+ if ( readyBound ) return;
+ readyBound = true;
+
+ // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
+ if ( document.addEventListener && !jQuery.browser.opera)
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
+
+ // If IE is used and is not in a frame
+ // Continually check to see if the document is ready
+ if ( jQuery.browser.msie && window == top ) (function(){
+ if (jQuery.isReady) return;
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch( error ) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+ // and execute any waiting functions
+ jQuery.ready();
+ })();
+
+ if ( jQuery.browser.opera )
+ document.addEventListener( "DOMContentLoaded", function () {
+ if (jQuery.isReady) return;
+ for (var i = 0; i < document.styleSheets.length; i++)
+ if (document.styleSheets[i].disabled) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+ // and execute any waiting functions
+ jQuery.ready();
+ }, false);
+
+ if ( jQuery.browser.safari ) {
+ var numStyles;
+ (function(){
+ if (jQuery.isReady) return;
+ if ( document.readyState != "loaded" && document.readyState != "complete" ) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+ if ( numStyles === undefined )
+ numStyles = jQuery("style, link[rel=stylesheet]").length;
+ if ( document.styleSheets.length != numStyles ) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+ // and execute any waiting functions
+ jQuery.ready();
+ })();
+ }
+
+ // A fallback to window.onload, that will always work
+ jQuery.event.add( window, "load", jQuery.ready );
+}
+
+jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
+ "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
+ "submit,keydown,keypress,keyup,error").split(","), function(i, name){
+
+ // Handle event binding
+ jQuery.fn[name] = function(fn){
+ return fn ? this.bind(name, fn) : this.trigger(name);
+ };
+});
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function(event, elem) {
+ // Check if mouse(over|out) are still within the same parent element
+ var parent = event.relatedTarget;
+ // Traverse up the tree
+ while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
+ // Return true if we actually just moused on to a sub-element
+ return parent == elem;
+};
+
+// Prevent memory leaks in IE
+// And prevent errors on refresh with events like mouseover in other browsers
+// Window isn't included so as not to unbind existing unload events
+jQuery(window).bind("unload", function() {
+ jQuery("*").add(document).unbind();
+});
+jQuery.fn.extend({
+ load: function( url, params, callback ) {
+ if ( jQuery.isFunction( url ) )
+ return this.bind("load", url);
+
+ var off = url.indexOf(" ");
+ if ( off >= 0 ) {
+ var selector = url.slice(off, url.length);
+ url = url.slice(0, off);
+ }
+
+ callback = callback || function(){};
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params )
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = null;
+
+ // Otherwise, build a param string
+ } else {
+ params = jQuery.param( params );
+ type = "POST";
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ dataType: "html",
+ data: params,
+ complete: function(res, status){
+ // If successful, inject the HTML into all the matched elements
+ if ( status == "success" || status == "notmodified" )
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div/>")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ res.responseText );
+
+ self.each( callback, [res.responseText, status, res] );
+ }
+ });
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param(this.serializeArray());
+ },
+ serializeArray: function() {
+ return this.map(function(){
+ return jQuery.nodeName(this, "form") ?
+ jQuery.makeArray(this.elements) : this;
+ })
+ .filter(function(){
+ return this.name && !this.disabled &&
+ (this.checked || /select|textarea/i.test(this.nodeName) ||
+ /text|hidden|password/i.test(this.type));
+ })
+ .map(function(i, elem){
+ var val = jQuery(this).val();
+ return val == null ? null :
+ val.constructor == Array ?
+ jQuery.map( val, function(val, i){
+ return {name: elem.name, value: val};
+ }) :
+ {name: elem.name, value: val};
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
+ jQuery.fn[o] = function(f){
+ return this.bind(o, f);
+ };
+});
+
+var jsc = (new Date).getTime();
+
+jQuery.extend({
+ get: function( url, data, callback, type ) {
+ // shift arguments if data argument was ommited
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = null;
+ }
+
+ return jQuery.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get(url, null, callback, "script");
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get(url, data, callback, "json");
+ },
+
+ post: function( url, data, callback, type ) {
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = {};
+ }
+
+ return jQuery.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ ajaxSetup: function( settings ) {
+ jQuery.extend( jQuery.ajaxSettings, settings );
+ },
+
+ ajaxSettings: {
+ global: true,
+ type: "GET",
+ timeout: 0,
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ data: null,
+ username: null,
+ password: null,
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ script: "text/javascript, application/javascript",
+ json: "application/json, text/javascript",
+ text: "text/plain",
+ _default: "*/*"
+ }
+ },
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+
+ ajax: function( s ) {
+ var jsonp, jsre = /=\?(&|$)/g, status, data;
+
+ // Extend the settings, but re-extend 's' so that it can be
+ // checked again later (in the test suite, specifically)
+ s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
+
+ // convert data if not already a string
+ if ( s.data && s.processData && typeof s.data != "string" )
+ s.data = jQuery.param(s.data);
+
+ // Handle JSONP Parameter Callbacks
+ if ( s.dataType == "jsonp" ) {
+ if ( s.type.toLowerCase() == "get" ) {
+ if ( !s.url.match(jsre) )
+ s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+ } else if ( !s.data || !s.data.match(jsre) )
+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+ s.dataType = "json";
+ }
+
+ // Build temporary JSONP function
+ if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
+ jsonp = "jsonp" + jsc++;
+
+ // Replace the =? sequence both in the query string and the data
+ if ( s.data )
+ s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+ s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+ // We need to make sure
+ // that a JSONP style response is executed properly
+ s.dataType = "script";
+
+ // Handle JSONP-style loading
+ window[ jsonp ] = function(tmp){
+ data = tmp;
+ success();
+ complete();
+ // Garbage collect
+ window[ jsonp ] = undefined;
+ try{ delete window[ jsonp ]; } catch(e){}
+ if ( head )
+ head.removeChild( script );
+ };
+ }
+
+ if ( s.dataType == "script" && s.cache == null )
+ s.cache = false;
+
+ if ( s.cache === false && s.type.toLowerCase() == "get" ) {
+ var ts = (new Date()).getTime();
+ // try replacing _= if it is there
+ var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
+ }
+
+ // If data is available, append data to url for get requests
+ if ( s.data && s.type.toLowerCase() == "get" ) {
+ s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
+
+ // IE likes to send both get and post data, prevent this
+ s.data = null;
+ }
+
+ // Watch for a new set of requests
+ if ( s.global && ! jQuery.active++ )
+ jQuery.event.trigger( "ajaxStart" );
+
+ // If we're requesting a remote document
+ // and trying to load JSON or Script with a GET
+ if ( (!s.url.indexOf("http") || !s.url.indexOf("//")) && s.dataType == "script" && s.type.toLowerCase() == "get" ) {
+ var head = document.getElementsByTagName("head")[0];
+ var script = document.createElement("script");
+ script.src = s.url;
+ if (s.scriptCharset)
+ script.charset = s.scriptCharset;
+
+ // Handle Script loading
+ if ( !jsonp ) {
+ var done = false;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function(){
+ if ( !done && (!this.readyState ||
+ this.readyState == "loaded" || this.readyState == "complete") ) {
+ done = true;
+ success();
+ complete();
+ head.removeChild( script );
+ }
+ };
+ }
+
+ head.appendChild(script);
+
+ // We handle everything using the script element injection
+ return undefined;
+ }
+
+ var requestDone = false;
+
+ // Create the request object; Microsoft failed to properly
+ // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
+ var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
+
+ // Open the socket
+ xml.open(s.type, s.url, s.async, s.username, s.password);
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ // Set the correct header, if data is being sent
+ if ( s.data )
+ xml.setRequestHeader("Content-Type", s.contentType);
+
+ // Set the If-Modified-Since header, if ifModified mode.
+ if ( s.ifModified )
+ xml.setRequestHeader("If-Modified-Since",
+ jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
+
+ // Set header so the called script knows that it's an XMLHttpRequest
+ xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+
+ // Set the Accepts header for the server, depending on the dataType
+ xml.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+ s.accepts[ s.dataType ] + ", */*" :
+ s.accepts._default );
+ } catch(e){}
+
+ // Allow custom headers/mimetypes
+ if ( s.beforeSend )
+ s.beforeSend(xml);
+
+ if ( s.global )
+ jQuery.event.trigger("ajaxSend", [xml, s]);
+
+ // Wait for a response to come back
+ var onreadystatechange = function(isTimeout){
+ // The transfer is complete and the data is available, or the request timed out
+ if ( !requestDone && xml && (xml.readyState == 4 || isTimeout == "timeout") ) {
+ requestDone = true;
+
+ // clear poll interval
+ if (ival) {
+ clearInterval(ival);
+ ival = null;
+ }
+
+ status = isTimeout == "timeout" && "timeout" ||
+ !jQuery.httpSuccess( xml ) && "error" ||
+ s.ifModified && jQuery.httpNotModified( xml, s.url ) && "notmodified" ||
+ "success";
+
+ if ( status == "success" ) {
+ // Watch for, and catch, XML document parse errors
+ try {
+ // process the data (runs the xml through httpData regardless of callback)
+ data = jQuery.httpData( xml, s.dataType );
+ } catch(e) {
+ status = "parsererror";
+ }
+ }
+
+ // Make sure that the request was successful or notmodified
+ if ( status == "success" ) {
+ // Cache Last-Modified header, if ifModified mode.
+ var modRes;
+ try {
+ modRes = xml.getResponseHeader("Last-Modified");
+ } catch(e) {} // swallow exception thrown by FF if header is not available
+
+ if ( s.ifModified && modRes )
+ jQuery.lastModified[s.url] = modRes;
+
+ // JSONP handles its own success callback
+ if ( !jsonp )
+ success();
+ } else
+ jQuery.handleError(s, xml, status);
+
+ // Fire the complete handlers
+ complete();
+
+ // Stop memory leaks
+ if ( s.async )
+ xml = null;
+ }
+ };
+
+ if ( s.async ) {
+ // don't attach the handler to the request, just poll it instead
+ var ival = setInterval(onreadystatechange, 13);
+
+ // Timeout checker
+ if ( s.timeout > 0 )
+ setTimeout(function(){
+ // Check to see if the request is still happening
+ if ( xml ) {
+ // Cancel the request
+ xml.abort();
+
+ if( !requestDone )
+ onreadystatechange( "timeout" );
+ }
+ }, s.timeout);
+ }
+
+ // Send the data
+ try {
+ xml.send(s.data);
+ } catch(e) {
+ jQuery.handleError(s, xml, null, e);
+ }
+
+ // firefox 1.5 doesn't fire statechange for sync requests
+ if ( !s.async )
+ onreadystatechange();
+
+ function success(){
+ // If a local callback was specified, fire it and pass it the data
+ if ( s.success )
+ s.success( data, status );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxSuccess", [xml, s] );
+ }
+
+ function complete(){
+ // Process result
+ if ( s.complete )
+ s.complete(xml, status);
+
+ // The request was completed
+ if ( s.global )
+ jQuery.event.trigger( "ajaxComplete", [xml, s] );
+
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ }
+
+ // return XMLHttpRequest to allow aborting the request etc.
+ return xml;
+ },
+
+ handleError: function( s, xml, status, e ) {
+ // If a local callback was specified, fire it
+ if ( s.error ) s.error( xml, status, e );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxError", [xml, s, e] );
+ },
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Determines if an XMLHttpRequest was successful or not
+ httpSuccess: function( r ) {
+ try {
+ // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+ return !r.status && location.protocol == "file:" ||
+ ( r.status >= 200 && r.status < 300 ) || r.status == 304 || r.status == 1223 ||
+ jQuery.browser.safari && r.status == undefined;
+ } catch(e){}
+ return false;
+ },
+
+ // Determines if an XMLHttpRequest returns NotModified
+ httpNotModified: function( xml, url ) {
+ try {
+ var xmlRes = xml.getResponseHeader("Last-Modified");
+
+ // Firefox always returns 200. check Last-Modified date
+ return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
+ jQuery.browser.safari && xml.status == undefined;
+ } catch(e){}
+ return false;
+ },
+
+ httpData: function( r, type ) {
+ var ct = r.getResponseHeader("content-type");
+ var xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0;
+ var data = xml ? r.responseXML : r.responseText;
+
+ if ( xml && data.documentElement.tagName == "parsererror" )
+ throw "parsererror";
+
+ // If the type is "script", eval it in global context
+ if ( type == "script" )
+ jQuery.globalEval( data );
+
+ // Get the JavaScript object, if JSON is used.
+ if ( type == "json" )
+ data = eval("(" + data + ")");
+
+ return data;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a ) {
+ var s = [];
+
+ // If an array was passed in, assume that it is an array
+ // of form elements
+ if ( a.constructor == Array || a.jquery )
+ // Serialize the form elements
+ jQuery.each( a, function(){
+ s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
+ });
+
+ // Otherwise, assume that it's an object of key/value pairs
+ else
+ // Serialize the key/values
+ for ( var j in a )
+ // If the value is an array then the key names need to be repeated
+ if ( a[j] && a[j].constructor == Array )
+ jQuery.each( a[j], function(){
+ s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
+ });
+ else
+ s.push( encodeURIComponent(j) + "=" + encodeURIComponent( a[j] ) );
+
+ // Return the resulting serialization
+ return s.join("&").replace(/%20/g, "+");
+ }
+
+});
+jQuery.fn.extend({
+ show: function(speed,callback){
+ return speed ?
+ this.animate({
+ height: "show", width: "show", opacity: "show"
+ }, speed, callback) :
+
+ this.filter(":hidden").each(function(){
+ this.style.display = this.oldblock || "";
+ if ( jQuery.css(this,"display") == "none" ) {
+ var elem = jQuery("<" + this.tagName + " />").appendTo("body");
+ this.style.display = elem.css("display");
+ // handle an edge condition where css is - div { display:none; } or similar
+ if (this.style.display == "none")
+ this.style.display = "block";
+ elem.remove();
+ }
+ }).end();
+ },
+
+ hide: function(speed,callback){
+ return speed ?
+ this.animate({
+ height: "hide", width: "hide", opacity: "hide"
+ }, speed, callback) :
+
+ this.filter(":visible").each(function(){
+ this.oldblock = this.oldblock || jQuery.css(this,"display");
+ this.style.display = "none";
+ }).end();
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2 ){
+ return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
+ this._toggle( fn, fn2 ) :
+ fn ?
+ this.animate({
+ height: "toggle", width: "toggle", opacity: "toggle"
+ }, fn, fn2) :
+ this.each(function(){
+ jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
+ });
+ },
+
+ slideDown: function(speed,callback){
+ return this.animate({height: "show"}, speed, callback);
+ },
+
+ slideUp: function(speed,callback){
+ return this.animate({height: "hide"}, speed, callback);
+ },
+
+ slideToggle: function(speed, callback){
+ return this.animate({height: "toggle"}, speed, callback);
+ },
+
+ fadeIn: function(speed, callback){
+ return this.animate({opacity: "show"}, speed, callback);
+ },
+
+ fadeOut: function(speed, callback){
+ return this.animate({opacity: "hide"}, speed, callback);
+ },
+
+ fadeTo: function(speed,to,callback){
+ return this.animate({opacity: to}, speed, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var optall = jQuery.speed(speed, easing, callback);
+
+ return this[ optall.queue === false ? "each" : "queue" ](function(){
+ if ( this.nodeType != 1)
+ return false;
+
+ var opt = jQuery.extend({}, optall);
+ var hidden = jQuery(this).is(":hidden"), self = this;
+
+ for ( var p in prop ) {
+ if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
+ return jQuery.isFunction(opt.complete) && opt.complete.apply(this);
+
+ if ( p == "height" || p == "width" ) {
+ // Store display property
+ opt.display = jQuery.css(this, "display");
+
+ // Make sure that nothing sneaks out
+ opt.overflow = this.style.overflow;
+ }
+ }
+
+ if ( opt.overflow != null )
+ this.style.overflow = "hidden";
+
+ opt.curAnim = jQuery.extend({}, prop);
+
+ jQuery.each( prop, function(name, val){
+ var e = new jQuery.fx( self, opt, name );
+
+ if ( /toggle|show|hide/.test(val) )
+ e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+ else {
+ var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
+ start = e.cur(true) || 0;
+
+ if ( parts ) {
+ var end = parseFloat(parts[2]),
+ unit = parts[3] || "px";
+
+ // We need to compute starting value
+ if ( unit != "px" ) {
+ self.style[ name ] = (end || 1) + unit;
+ start = ((end || 1) / e.cur(true)) * start;
+ self.style[ name ] = start + unit;
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] )
+ end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
+
+ e.custom( start, end, unit );
+ } else
+ e.custom( start, val, "" );
+ }
+ });
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ queue: function(type, fn){
+ if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
+ fn = type;
+ type = "fx";
+ }
+
+ if ( !type || (typeof type == "string" && !fn) )
+ return queue( this[0], type );
+
+ return this.each(function(){
+ if ( fn.constructor == Array )
+ queue(this, type, fn);
+ else {
+ queue(this, type).push( fn );
+
+ if ( queue(this, type).length == 1 )
+ fn.apply(this);
+ }
+ });
+ },
+
+ stop: function(clearQueue, gotoEnd){
+ var timers = jQuery.timers;
+
+ if (clearQueue)
+ this.queue([]);
+
+ this.each(function(){
+ // go in reverse order so anything added to the queue during the loop is ignored
+ for ( var i = timers.length - 1; i >= 0; i-- )
+ if ( timers[i].elem == this ) {
+ if (gotoEnd)
+ // force the next step to be the last
+ timers[i](true);
+ timers.splice(i, 1);
+ }
+ });
+
+ // start the next in the queue if the last step wasn't forced
+ if (!gotoEnd)
+ this.dequeue();
+
+ return this;
+ }
+
+});
+
+var queue = function( elem, type, array ) {
+ if ( !elem )
+ return undefined;
+
+ type = type || "fx";
+
+ var q = jQuery.data( elem, type + "queue" );
+
+ if ( !q || array )
+ q = jQuery.data( elem, type + "queue",
+ array ? jQuery.makeArray(array) : [] );
+
+ return q;
+};
+
+jQuery.fn.dequeue = function(type){
+ type = type || "fx";
+
+ return this.each(function(){
+ var q = queue(this, type);
+
+ q.shift();
+
+ if ( q.length )
+ q[0].apply( this );
+ });
+};
+
+jQuery.extend({
+
+ speed: function(speed, easing, fn) {
+ var opt = speed && speed.constructor == Object ? speed : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && easing.constructor != Function && easing
+ };
+
+ opt.duration = (opt.duration && opt.duration.constructor == Number ?
+ opt.duration :
+ { slow: 600, fast: 200 }[opt.duration]) || 400;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function(){
+ if ( opt.queue !== false )
+ jQuery(this).dequeue();
+ if ( jQuery.isFunction( opt.old ) )
+ opt.old.apply( this );
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+ timerId: null,
+
+ fx: function( elem, options, prop ){
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ if ( !options.orig )
+ options.orig = {};
+ }
+
+});
+
+jQuery.fx.prototype = {
+
+ // Simple function for setting a style value
+ update: function(){
+ if ( this.options.step )
+ this.options.step.apply( this.elem, [ this.now, this ] );
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+ // Set display property to block for height/width animations
+ if ( this.prop == "height" || this.prop == "width" )
+ this.elem.style.display = "block";
+ },
+
+ // Get the current size
+ cur: function(force){
+ if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
+ return this.elem[ this.prop ];
+
+ var r = parseFloat(jQuery.css(this.elem, this.prop, force));
+ return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
+ },
+
+ // Start an animation from one number to another
+ custom: function(from, to, unit){
+ this.startTime = (new Date()).getTime();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || "px";
+ this.now = this.start;
+ this.pos = this.state = 0;
+ this.update();
+
+ var self = this;
+ function t(gotoEnd){
+ return self.step(gotoEnd);
+ }
+
+ t.elem = this.elem;
+
+ jQuery.timers.push(t);
+
+ if ( jQuery.timerId == null ) {
+ jQuery.timerId = setInterval(function(){
+ var timers = jQuery.timers;
+
+ for ( var i = 0; i < timers.length; i++ )
+ if ( !timers[i]() )
+ timers.splice(i--, 1);
+
+ if ( !timers.length ) {
+ clearInterval( jQuery.timerId );
+ jQuery.timerId = null;
+ }
+ }, 13);
+ }
+ },
+
+ // Simple 'show' function
+ show: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ this.custom(0, this.cur());
+
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ if ( this.prop == "width" || this.prop == "height" )
+ this.elem.style[this.prop] = "1px";
+
+ // Start by showing the element
+ jQuery(this.elem).show();
+ },
+
+ // Simple 'hide' function
+ hide: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function(gotoEnd){
+ var t = (new Date()).getTime();
+
+ if ( gotoEnd || t > this.options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ this.options.curAnim[ this.prop ] = true;
+
+ var done = true;
+ for ( var i in this.options.curAnim )
+ if ( this.options.curAnim[i] !== true )
+ done = false;
+
+ if ( done ) {
+ if ( this.options.display != null ) {
+ // Reset the overflow
+ this.elem.style.overflow = this.options.overflow;
+
+ // Reset the display
+ this.elem.style.display = this.options.display;
+ if ( jQuery.css(this.elem, "display") == "none" )
+ this.elem.style.display = "block";
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( this.options.hide )
+ this.elem.style.display = "none";
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( this.options.hide || this.options.show )
+ for ( var p in this.options.curAnim )
+ jQuery.attr(this.elem.style, p, this.options.orig[p]);
+ }
+
+ // If a callback was provided, execute it
+ if ( done && jQuery.isFunction( this.options.complete ) )
+ // Execute the complete function
+ this.options.complete.apply( this.elem );
+
+ return false;
+ } else {
+ var n = t - this.startTime;
+ this.state = n / this.options.duration;
+
+ // Perform the easing function, defaults to swing
+ this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
+ this.now = this.start + ((this.end - this.start) * this.pos);
+
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+
+};
+
+jQuery.fx.step = {
+ scrollLeft: function(fx){
+ fx.elem.scrollLeft = fx.now;
+ },
+
+ scrollTop: function(fx){
+ fx.elem.scrollTop = fx.now;
+ },
+
+ opacity: function(fx){
+ jQuery.attr(fx.elem.style, "opacity", fx.now);
+ },
+
+ _default: function(fx){
+ fx.elem.style[ fx.prop ] = fx.now + fx.unit;
+ }
+};
+// The Offset Method
+// Originally By Brandon Aaron, part of the Dimension Plugin
+// http://jquery.com/plugins/project/dimensions
+jQuery.fn.offset = function() {
+ var left = 0, top = 0, elem = this[0], results;
+
+ if ( elem ) with ( jQuery.browser ) {
+ var parent = elem.parentNode,
+ offsetChild = elem,
+ offsetParent = elem.offsetParent,
+ doc = elem.ownerDocument,
+ safari2 = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),
+ fixed = jQuery.css(elem, "position") == "fixed";
+
+ // Use getBoundingClientRect if available
+ if ( elem.getBoundingClientRect ) {
+ var box = elem.getBoundingClientRect();
+
+ // Add the document scroll offsets
+ add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
+ box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
+
+ // IE adds the HTML element's border, by default it is medium which is 2px
+ // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
+ // IE 7 standards mode, the border is always 2px
+ // This border/offset is typically represented by the clientLeft and clientTop properties
+ // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
+ // Therefore this method will be off by 2px in IE while in quirksmode
+ add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
+
+ // Otherwise loop through the offsetParents and parentNodes
+ } else {
+
+ // Initial element offsets
+ add( elem.offsetLeft, elem.offsetTop );
+
+ // Get parent offsets
+ while ( offsetParent ) {
+ // Add offsetParent offsets
+ add( offsetParent.offsetLeft, offsetParent.offsetTop );
+
+ // Mozilla and Safari > 2 does not include the border on offset parents
+ // However Mozilla adds the border for table or table cells
+ if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
+ border( offsetParent );
+
+ // Add the document scroll offsets if position is fixed on any offsetParent
+ if ( !fixed && jQuery.css(offsetParent, "position") == "fixed" )
+ fixed = true;
+
+ // Set offsetChild to previous offsetParent unless it is the body element
+ offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
+ // Get next offsetParent
+ offsetParent = offsetParent.offsetParent;
+ }
+
+ // Get parent scroll offsets
+ while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
+ // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
+ if ( !/^inline|table.*$/i.test(jQuery.css(parent, "display")) )
+ // Subtract parent scroll offsets
+ add( -parent.scrollLeft, -parent.scrollTop );
+
+ // Mozilla does not add the border for a parent that has overflow != visible
+ if ( mozilla && jQuery.css(parent, "overflow") != "visible" )
+ border( parent );
+
+ // Get next parent
+ parent = parent.parentNode;
+ }
+
+ // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
+ // Mozilla doubles body offsets with a non-absolutely positioned offsetChild
+ if ( (safari2 && (fixed || jQuery.css(offsetChild, "position") == "absolute")) ||
+ (mozilla && jQuery.css(offsetChild, "position") != "absolute") )
+ add( -doc.body.offsetLeft, -doc.body.offsetTop );
+
+ // Add the document scroll offsets if position is fixed
+ if ( fixed )
+ add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
+ Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
+ }
+
+ // Return an object with top and left properties
+ results = { top: top, left: left };
+ }
+
+ function border(elem) {
+ add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
+ }
+
+ function add(l, t) {
+ left += parseInt(l) || 0;
+ top += parseInt(t) || 0;
+ }
+
+ return results;
+};
+})();
diff --git a/web/legal.txt b/web/legal.txt
new file mode 100644
index 0000000..ea8f9ff
--- /dev/null
+++ b/web/legal.txt
@@ -0,0 +1,72 @@
+SOCIALCALC LEGAL.txt FILE:
+
+LEGAL INFORMATION
+
+This LEGAL.txt file accompanies the SocialCalc program. It includes notices required by the
+licenses as well as general legal notices.
+
+=========================================
+ COPYRIGHT AND ATTRIBUTION NOTICES
+=========================================
+
+Copyright (C) 2009 Socialtext, Inc.
+All Rights Reserved.
+
+image:sc-logo.gif
+"SocialCalc"
+http://www.socialcalc.org/xoattrib
+
+=========================================
+ SOURCE CODE AVAILABILITY NOTICE
+=========================================
+
+The source code for this product is available from:
+http://socialcalc.org/.
+
+=========================================
+ GENERAL LEGAL NOTICES
+=========================================
+
+wikiCalc, Garden, and Software Garden are registered trademarks of Software Garden, Inc.
+Socialtext and SocialCalc are registered trademarks of Socialtext, Inc.
+The Socialtext logo and Dreamcatcher are trademarks of Socialtext, Inc.
+
+=========================================
+ LEGAL NOTICES REQUIRED BY THE LICENSE
+=========================================
+
+CHANGES MADE TO THE COVERED CODE (see CPAL Version 1.0 Section 3.3):
+
+2008-02-08:
+ Original Code started as a translation to JavaScript of code in SocialCalc 1.1.0 plus
+ much new code.
+
+ Python code for the OLPC XO-1 initially coded by Luke Closs of Socialtext, Inc.
+
+ JavaScript initially coded by Dan Bricklin of Software Garden, Inc., for Socialtext, Inc.
+ Based in part on the SocialCalc 1.1.0 code written in Perl.
+ The SocialCalc 1.1.0 code was:
+ Portions (c) Copyright 2005, 2006, 2007 Software Garden, Inc.
+ All Rights Reserved.
+ Portions (c) Copyright 2007 Socialtext, Inc.
+ All Rights Reserved.
+ The Perl SocialCalc started as modifications to the wikiCalc(R) program, version 1.0.
+ wikiCalc 1.0 was written by Software Garden, Inc.
+ Unless otherwise specified, referring to "SocialCalc" in comments refers to this
+ JavaScript version of the code, not the SocialCalc Perl code.
+
+----------
+
+(Documentation of future changes as the result of Modifications, including the date of
+change, will go here in this LEGAL.txt file. This documentation may be summaries of
+changes with the more detailed descriptions included in the actual modified files as
+appropriate.)
+
+==========
+
+THIRD PARTY CLAIMS (see CPAL Version 1.0 Section 3.4(a)):
+
+None.
+
+[End of LEGAL.txt]
+
diff --git a/web/license.txt b/web/license.txt
new file mode 100644
index 0000000..0827902
--- /dev/null
+++ b/web/license.txt
@@ -0,0 +1,705 @@
+SOCIALCALC LICENSE.txt FILE:
+
+=========================================
+ ABOUT THIS FILE
+=========================================
+
+This file includes copies of the Common Public Attribution License (CPAL) and
+the Artistic License 2.0.
+
+This product consists of components licensed under different licenses.
+Check the contents of each file for a statement of the license for that file.
+Files without license information are licensed under the Artistic License 2.0.
+
+======================================================
+ COMMON PUBLIC ATTRIBUTION LICENSE VERSION 1.0 (CPAL)
+======================================================
+
+Common Public Attribution License Version 1.0 (CPAL)
+
+1. "Definitions"
+
+1.0.1 "Commercial Use" means distribution or otherwise making the Covered Code
+available to a third party.
+
+1.1 "Contributor" means each entity that creates or contributes to the creation
+of Modifications.
+
+1.2 "Contributor Version" means the combination of the Original Code, prior
+Modifications used by a Contributor, and the Modifications made by that particular
+Contributor.
+
+1.3 "Covered Code" means the Original Code or Modifications or the combination of
+the Original Code and Modifications, in each case including portions thereof.
+
+1.4 "Electronic Distribution Mechanism" means a mechanism generally accepted in
+the software development community for the electronic transfer of data.
+
+1.5 "Executable" means Covered Code in any form other than Source Code.
+
+1.6 "Initial Developer" means the individual or entity identified as the Initial
+Developer in the Source Code notice required by Exhibit A.
+
+1.7 "Larger Work" means a work which combines Covered Code or portions thereof with
+code not governed by the terms of this License.
+
+1.8 "License" means this document.
+
+1.8.1 "Licensable" means having the right to grant, to the maximum extent possible,
+whether at the time of the initial grant or subsequently acquired, any and all of
+the rights conveyed herein.
+
+1.9 "Modifications" means any addition to or deletion from the substance or structure
+of either the Original Code or any previous Modifications. When Covered Code is
+released as a series of files, a Modification is:
+
+A. Any addition to or deletion from the contents of a file containing Original Code
+or previous Modifications.
+
+B. Any new file that contains any part of the Original Code or previous Modifications.
+
+1.10 "Original Code" means Source Code of computer software code which is described in
+the Source Code notice required by Exhibit A as Original Code, and which, at the time
+of its release under this License is not already Covered Code governed by this License.
+
+1.10.1 "Patent Claims" means any patent claim(s), now owned or hereafter acquired,
+including without limitation, method, process, and apparatus claims, in any patent
+Licensable by grantor.
+
+1.11 "Source Code" means the preferred form of the Covered Code for making modifications
+to it, including all modules it contains, plus any associated interface definition files,
+scripts used to control compilation and installation of an Executable, or source code
+differential comparisons against either the Original Code or another well known,
+available Covered Code of the Contributor’s choice. The Source Code can be in a compressed
+or archival form, provided the appropriate decompression or de-archiving software is
+widely available for no charge.
+
+1.12 "You" (or "Your") means an individual or a legal entity exercising rights under, and
+complying with all of the terms of, this License or a future version of this License
+issued under Section 6.1. For legal entities, "You" includes any entity which controls,
+is controlled by, or is under common control with You. For purposes of this definition,
+"control" means (a) the power, direct or indirect, to cause the direction or management
+of such entity, whether by contract or otherwise, or (b) ownership of more than fifty
+percent (50%) of the outstanding shares or beneficial ownership of such entity.
+
+2. Source Code License.
+
+2.1 The Initial Developer Grant.
+
+The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive
+license, subject to third party intellectual property claims:
+
+(a) under intellectual property rights (other than patent or trademark) Licensable by
+Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute
+the Original Code (or portions thereof) with or without Modifications, and/or as part
+of a Larger Work; and
+
+(b) under Patents Claims infringed by the making, using or selling of Original Code, to
+make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of
+the Original Code (or portions thereof).
+
+(c) the licenses granted in this Section 2.1(a) and (b) are effective on the date
+Initial Developer first distributes Original Code under the terms of this License.
+
+(d) Notwithstanding Section 2.1(b) above, no patent license is granted: 1) for code
+that You delete from the Original Code; 2) separate from the Original Code; or 3) for
+infringements caused by: i) the modification of the Original Code or ii) the combination
+of the Original Code with other software or devices.
+
+2.2 Contributor Grant.
+
+Subject to third party intellectual property claims, each Contributor hereby grants You
+a world-wide, royalty-free, non-exclusive license
+
+(a) under intellectual property rights (other than patent or trademark) Licensable by
+Contributor, to use, reproduce, modify, display, perform, sublicense and distribute
+the Modifications created by such Contributor (or portions thereof) either on an
+unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger
+Work; and
+
+(b) under Patent Claims infringed by the making, using, or selling of Modifications
+made by that Contributor either alone and/or in combination with its Contributor
+Version (or portions of such combination), to make, use, sell, offer for sale, have
+made, and/or otherwise dispose of: 1) Modifications made by that Contributor (or
+portions thereof); and 2) the combination of Modifications made by that Contributor
+with its Contributor Version (or portions of such combination).
+
+(c) the licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date
+Contributor first makes Commercial Use of the Covered Code.
+
+(d) Notwithstanding Section 2.2(b) above, no patent license is granted: 1) for any code
+that Contributor has deleted from the Contributor Version; 2) separate from the
+Contributor Version; 3) for infringements caused by: i) third party modifications of
+Contributor Version or ii) the combination of Modifications made by that Contributor
+with other software (except as part of the Contributor Version) or other devices; or
+4) under Patent Claims infringed by Covered Code in the absence of Modifications made
+by that Contributor.
+
+3. Distribution Obligations.
+
+3.1 Application of License.
+
+The Modifications which You create or to which You contribute are governed by the terms
+of this License, including without limitation Section 2.2. The Source Code version of
+Covered Code may be distributed only under the terms of this License or a future version
+of this License released under Section 6.1, and You must include a copy of this License
+with every copy of the Source Code You distribute. You may not offer or impose any terms
+on any Source Code version that alters or restricts the applicable version of this License
+or the recipients’ rights hereunder. However, You may include an additional document
+offering the additional rights described in Section 3.5.
+
+3.2 Availability of Source Code.
+
+Any Modification which You create or to which You contribute must be made available in
+Source Code form under the terms of this License either on the same media as an Executable
+version or via an accepted Electronic Distribution Mechanism to anyone to whom you made
+an Executable version available; and if made available via Electronic Distribution
+Mechanism, must remain available for at least twelve (12) months after the date it
+initially became available, or at least six (6) months after a subsequent version of that
+particular Modification has been made available to such recipients. You are responsible
+for ensuring that the Source Code version remains available even if the Electronic
+Distribution Mechanism is maintained by a third party.
+
+3.3 Description of Modifications.
+
+You must cause all Covered Code to which You contribute to contain a file documenting the
+changes You made to create that Covered Code and the date of any change. You must include
+a prominent statement that the Modification is derived, directly or indirectly, from
+Original Code provided by the Initial Developer and including the name of the Initial
+Developer in (a) the Source Code, and (b) in any notice in an Executable version or
+related documentation in which You describe the origin or ownership of the Covered Code.
+
+3.4 Intellectual Property Matters
+
+(a) Third Party Claims.
+
+If Contributor has knowledge that a license under a third party’s intellectual property
+rights is required to exercise the rights granted by such Contributor under Sections 2.1
+or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL"
+which describes the claim and the party making the claim in sufficient detail that a
+recipient will know whom to contact. If Contributor obtains such knowledge after the
+Modification is made available as described in Section 3.2, Contributor shall promptly
+modify the LEGAL file in all copies Contributor makes available thereafter and shall take
+other steps (such as notifying appropriate mailing lists or newsgroups) reasonably
+calculated to inform those who received the Covered Code that new knowledge has been obtained.
+
+(b) Contributor APIs.
+
+If Contributor’s Modifications include an application programming interface and Contributor
+has knowledge of patent licenses which are reasonably necessary to implement that API,
+Contributor must also include this information in the LEGAL file.
+
+(c) Representations.
+
+Contributor represents that, except as disclosed pursuant to Section 3.4(a) above, Contributor
+believes that Contributor’s Modifications are Contributor’s original creation(s) and/or
+Contributor has sufficient rights to grant the rights conveyed by this License.
+
+3.5 Required Notices.
+
+You must duplicate the notice in Exhibit A in each file of the Source Code. If it is not
+possible to put such notice in a particular Source Code file due to its structure, then
+You must include such notice in a location (such as a relevant directory) where a user
+would be likely to look for such a notice. If You created one or more Modification(s)
+You may add your name as a Contributor to the notice described in Exhibit A. You must
+also duplicate this License in any documentation for the Source Code where You describe
+recipients’ rights or ownership rights relating to Covered Code. You may choose to offer,
+and to charge a fee for, warranty, support, indemnity or liability obligations to one or
+more recipients of Covered Code. However, You may do so only on Your own behalf, and not
+on behalf of the Initial Developer or any Contributor. You must make it absolutely clear
+than any such warranty, support, indemnity or liability obligation is offered by You alone,
+and You hereby agree to indemnify the Initial Developer and every Contributor for any
+liability incurred by the Initial Developer or such Contributor as a result of warranty,
+support, indemnity or liability terms You offer.
+
+3.6 Distribution of Executable Versions.
+
+You may distribute Covered Code in Executable form only if the requirements of Section
+3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the
+Source Code version of the Covered Code is available under the terms of this License,
+including a description of how and where You have fulfilled the obligations of Section
+3.2. The notice must be conspicuously included in any notice in an Executable version,
+related documentation or collateral in which You describe recipients’ rights relating to
+the Covered Code. You may distribute the Executable version of Covered Code or ownership
+rights under a license of Your choice, which may contain terms different from this License,
+provided that You are in compliance with the terms of this License and that the license for
+the Executable version does not attempt to limit or alter the recipient’s rights in the
+Source Code version from the rights set forth in this License. If You distribute the
+Executable version under a different license You must make it absolutely clear that any
+terms which differ from this License are offered by You alone, not by the Initial Developer,
+Original Developer or any Contributor. You hereby agree to indemnify the Initial Developer,
+Original Developer and every Contributor for any liability incurred by the Initial Developer,
+Original Developer or such Contributor as a result of any such terms You offer.
+
+3.7 Larger Works.
+
+You may create a Larger Work by combining Covered Code with other code not governed by the
+terms of this License and distribute the Larger Work as a single product. In such a case, You
+must make sure the requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+If it is impossible for You to comply with any of the terms of this License with respect to
+some or all of the Covered Code due to statute, judicial order, or regulation then You must:
+(a) comply with the terms of this License to the maximum extent possible; and (b) describe the
+limitations and the code they affect. Such description must be included in the LEGAL file
+described in Section 3.4 and must be included with all distributions of the Source Code.
+Except to the extent prohibited by statute or regulation, such description must be
+sufficiently detailed for a recipient of ordinary skill to be able to understand it.
+
+5. Application of this License.
+
+This License applies to code to which the Initial Developer has attached the notice in Exhibit
+A and to related Covered Code.
+
+6. Versions of the License.
+
+6.1 New Versions.
+
+Socialtext, Inc. ("Socialtext") may publish revised and/or new versions of the License from
+time to time. Each version will be given a distinguishing version number.
+
+6.2 Effect of New Versions.
+
+Once Covered Code has been published under a particular version of the License, You may always
+continue to use it under the terms of that version. You may also choose to use such Covered
+Code under the terms of any subsequent version of the License published by Socialtext. No one
+other than Socialtext has the right to modify the terms applicable to Covered Code created
+under this License.
+
+6.3 Derivative Works.
+
+If You create or use a modified version of this License (which you may only do in order to
+apply it to code which is not already Covered Code governed by this License), You must (a)
+rename Your license so that the phrases "Socialtext", "CPAL" or any confusingly similar phrase
+do not appear in your license (except to note that your license differs from this License) and
+(b) otherwise make it clear that Your version of the license contains terms which differ from
+the CPAL. (Filling in the name of the Initial Developer, Original Developer, Original Code or
+Contributor in the notice described in Exhibit A shall not of themselves be deemed to be
+modifications of this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND,
+EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS
+FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK
+AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE
+DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER, ORIGINAL DEVELOPER OR ANY OTHER
+CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS
+AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+8.1 This License and the rights granted hereunder will terminate automatically if You fail to
+comply with terms herein and fail to cure such breach within 30 days of becoming aware of the
+breach. All sublicenses to the Covered Code which are properly granted shall survive any
+termination of this License. Provisions which, by their nature, must remain in effect beyond
+the termination of this License shall survive.
+
+8.2 If You initiate litigation by asserting a patent infringement claim (excluding declatory
+judgment actions) against Initial Developer, Original Developer or a Contributor (the Initial
+Developer, Original Developer or Contributor against whom You file such action is referred to
+as "Participant") alleging that:
+
+(a) such Participant’s Contributor Version directly or indirectly infringes any patent, then
+any and all rights granted by such Participant to You under Sections 2.1 and/or 2.2 of this
+License shall, upon 60 days notice from Participant terminate prospectively, unless if within
+60 days after receipt of notice You either: (i) agree in writing to pay Participant a mutually
+agreeable reasonable royalty for Your past and future use of Modifications made by such
+Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version
+against such Participant. If within 60 days of notice, a reasonable royalty and payment
+arrangement are not mutually agreed upon in writing by the parties or the litigation claim is
+not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2
+automatically terminate at the expiration of the 60 day notice period specified above.
+
+(b) any software, hardware, or device, other than such Participant’s Contributor Version,
+directly or indirectly infringes any patent, then any rights granted to You by such Participant
+under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used,
+sold, distributed, or had made, Modifications made by that Participant.
+
+8.3 If You assert a patent infringement claim against Participant alleging that such
+Participant’s Contributor Version directly or indirectly infringes any patent where such claim
+is resolved (such as by license or settlement) prior to the initiation of patent infringement
+litigation, then the reasonable value of the licenses granted by such Participant under Sections
+2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or
+license.
+
+8.4 In the event of termination under Sections 8.1 or 8.2 above, all end user license agreements
+(excluding distributors and resellers) which have been validly granted by You or any distributor
+hereunder prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT,
+OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ORIGINAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR
+ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON
+FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING,
+WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION,
+OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF
+THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR
+DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY’S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+The Covered Code is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995),
+consisting of "commercial computer software" and "commercial computer software documentation," as
+such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48
+C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered
+Code with only those rights set forth herein.
+
+11. MISCELLANEOUS.
+
+This License represents the complete agreement concerning subject matter hereof. If any provision
+of this License is held to be unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. This License shall be governed by California law provisions
+(except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law
+provisions. With respect to disputes in which at least one party is a citizen of, or an entity
+chartered or registered to do business in the United States of America, any litigation relating to
+this License shall be subject to the jurisdiction of the Federal Courts of the Northern District
+of California, with venue lying in Santa Clara County, California, with the losing party
+responsible for costs, including without limitation, court costs and reasonable attorneys’ fees
+and expenses. The application of the United Nations Convention on Contracts for the International
+Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a
+contract shall be construed against the drafter shall not apply to this License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+As between Initial Developer, Original Developer and the Contributors, each party is responsible
+for claims and damages arising, directly or indirectly, out of its utilization of rights under
+this License and You agree to work with Initial Developer, Original Developer and Contributors to
+distribute such responsibility on an equitable basis. Nothing herein is intended or shall be
+deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+Initial Developer may designate portions of the Covered Code as Multiple-Licensed.
+Multiple-Licensed means that the Initial Developer permits you to utilize portions of the Covered
+Code under Your choice of the CPAL or the alternative licenses, if any, specified by the Initial
+Developer in the file described in Exhibit A.
+
+14. ADDITIONAL TERM: ATTRIBUTION
+
+(a) As a modest attribution to the organizer of the development of the Original Code ("Original
+Developer"), in the hope that its promotional value may help justify the time, money and effort
+invested in writing the Original Code, the Original Developer may include in Exhibit B
+("Attribution Information") a requirement that each time an Executable and Source Code or a Larger
+Work is launched or initially run (which includes initiating a session), a prominent display of
+the Original Developer’s Attribution Information (as defined below) must occur on the graphic user
+interface employed by the end user to access such Covered Code (which may include display on a
+splash screen), if any. The size of the graphic image should be consistent with the size of the
+other elements of the Attribution Information. If the access by the end user to the Executable and
+Source Code does not create a graphic user interface for access to the Covered Code, this
+obligation shall not apply. If the Original Code displays such Attribution Information in a
+particular form (such as in the form of a splash screen, notice at login, an "about" display, or
+dedicated attribution area on user interface screens), continued use of such form for that
+Attribution Information is one way of meeting this requirement for notice.
+
+(b) Attribution information may only include a copyright notice, a brief phrase, graphic image and
+a URL ("Attribution Information") and is subject to the Attribution Limits as defined below. For
+these purposes, prominent shall mean display for sufficient duration to give reasonable notice to
+the user of the identity of the Original Developer and that if You include Attribution Information
+or similar information for other parties, You must ensure that the Attribution Information for the
+Original Developer shall be no less prominent than such Attribution Information or similar
+information for the other party. For greater certainty, the Original Developer may choose to
+specify in Exhibit B below that the above attribution requirement only applies to an Executable
+and Source Code resulting from the Original Code or any Modification, but not a Larger Work. The
+intent is to provide for reasonably modest attribution, therefore the Original Developer cannot
+require that You display, at any time, more than the following information as Attribution
+Information: (a) a copyright notice including the name of the Original Developer; (b) a word or
+one phrase (not exceeding 10 words); (c) one graphic image provided by the Original Developer; and
+(d) a URL (collectively, the "Attribution Limits").
+
+(c) If Exhibit B does not include any Attribution Information, then there are no requirements for
+You to display any Attribution Information of the Original Developer.
+
+(d) You acknowledge that all trademarks, service marks and/or trade names contained within the
+Attribution Information distributed with the Covered Code are the exclusive property of their
+owners and may only be used with the permission of their owners, or under circumstances otherwise
+permitted by law or as expressly set out in this License.
+
+15. ADDITIONAL TERM: NETWORK USE.
+The term "External Deployment" means the use, distribution, or communication of the Original Code
+or Modifications in any way such that the Original Code or Modifications may be used by anyone
+other than You, whether those works are distributed or communicated to those persons or made
+available as an application intended for use over a network. As an express condition for the grants
+of license hereunder, You must treat any External Deployment by You of the Original Code or
+Modifications as a distribution under section 3.1 and make Source Code available under Section 3.2.
+
+EXHIBIT A. Common Public Attribution License Version 1.0.
+
+"The contents of this file are subject to the Common Public Attribution License Version 1.0 (the
+"License"); you may not use this file except in compliance with the License. You may obtain a copy
+of the License at _____________. The License is based on the Mozilla Public License Version 1.1 but
+Sections 14 and 15 have been added to cover use of software over a computer network and provide for
+limited attribution for the Original Developer. In addition, Exhibit A has been modified to be
+consistent with Exhibit B.
+
+Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+KIND, either express or implied. See the License for the specific language governing rights and
+limitations under the License.
+
+The Original Code is______________________.
+
+The Original Developer is not the Initial Developer and is __________. If left blank, the Original
+Developer is the Initial Developer.
+
+The Initial Developer of the Original Code is ____________. All portions of the code written by
+___________ are Copyright (c) _____. All Rights Reserved.
+
+Contributor ______________________.
+
+Alternatively, the contents of this file may be used under the terms of the _____ license (the
+[___] License), in which case the provisions of [______] License are applicable instead of those
+above.
+
+If you wish to allow use of your version of this file only under the terms of the [____] License
+and not to allow others to use your version of this file under the CPAL, indicate your decision by
+deleting the provisions above and replace them with the notice and other provisions required by
+the [___] License. If you do not delete the provisions above, a recipient may use your version of
+this file under either the CPAL or the [___] License."
+
+[NOTE: The text of this Exhibit A may differ slightly from the text of the notices in the Source
+Code files of the Original Code. You should use the text of this Exhibit A rather than the text
+found in the Original Code Source Code for Your Modifications.]
+
+EXHIBIT B. Attribution Information
+
+When the TableEditor is producing and/or controlling the display the Graphic Image must be
+displayed on the screen visible to the user in a manner comparable to that in the
+Original Code. The Attribution Phrase must be displayed as a "tooltip" or "hover-text" for
+that image. The image must be linked to the Attribution URL so as to access that page
+when clicked. If the user interface includes a prominent "about" display which includes
+factual prominent attribution in a form similar to that in the "about" display included
+with the Original Code, including Socialtext copyright notices and URLs, then the image
+need not be linked to the Attribution URL but the "tool-tip" is still required.
+
+Attribution Copyright Notice:
+
+ Copyright (C) 2009 Socialtext, Inc.
+ All Rights Reserved.
+
+Attribution Phrase (not exceeding 10 words): SocialCalc
+
+Attribution URL: http://www.socialcalc.org
+
+Graphic Image: The contents of the sc-logo.gif file in the Original Code or
+a suitable replacement from http://www.socialcalc.org/licenses specified as
+being for SocialCalc.
+
+Display of Attribution Information is required in Larger Works which are defined
+in the CPAL as a work which combines Covered Code or portions thereof with code
+not governed by the terms of the CPAL.
+
+
+=========================================
+ THE ARTISTIC LICENSE 2.0
+=========================================
+
+ The Artistic License 2.0
+
+ Copyright (c) 2000-2006, The Perl Foundation.
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+Preamble
+
+This license establishes the terms under which a given free software
+Package may be copied, modified, distributed, and/or redistributed.
+The intent is that the Copyright Holder maintains some artistic
+control over the development of that Package while still keeping the
+Package available as open source and free software.
+
+You are always permitted to make arrangements wholly outside of this
+license directly with the Copyright Holder of a given Package. If the
+terms of this license do not permit the full use that you propose to
+make of the Package, you should contact the Copyright Holder and seek
+a different licensing arrangement.
+
+Definitions
+
+ "Copyright Holder" means the individual(s) or organization(s)
+ named in the copyright notice for the entire Package.
+
+ "Contributor" means any party that has contributed code or other
+ material to the Package, in accordance with the Copyright Holder's
+ procedures.
+
+ "You" and "your" means any person who would like to copy,
+ distribute, or modify the Package.
+
+ "Package" means the collection of files distributed by the
+ Copyright Holder, and derivatives of that collection and/or of
+ those files. A given Package may consist of either the Standard
+ Version, or a Modified Version.
+
+ "Distribute" means providing a copy of the Package or making it
+ accessible to anyone else, or in the case of a company or
+ organization, to others outside of your company or organization.
+
+ "Distributor Fee" means any fee that you charge for Distributing
+ this Package or providing support for this Package to another
+ party. It does not mean licensing fees.
+
+ "Standard Version" refers to the Package if it has not been
+ modified, or has been modified only in ways explicitly requested
+ by the Copyright Holder.
+
+ "Modified Version" means the Package, if it has been changed, and
+ such changes were not explicitly requested by the Copyright
+ Holder.
+
+ "Original License" means this Artistic License as Distributed with
+ the Standard Version of the Package, in its current version or as
+ it may be modified by The Perl Foundation in the future.
+
+ "Source" form means the source code, documentation source, and
+ configuration files for the Package.
+
+ "Compiled" form means the compiled bytecode, object code, binary,
+ or any other form resulting from mechanical transformation or
+ translation of the Source form.
+
+
+Permission for Use and Modification Without Distribution
+
+(1) You are permitted to use the Standard Version and create and use
+Modified Versions for any purpose without restriction, provided that
+you do not Distribute the Modified Version.
+
+
+Permissions for Redistribution of the Standard Version
+
+(2) You may Distribute verbatim copies of the Source form of the
+Standard Version of this Package in any medium without restriction,
+either gratis or for a Distributor Fee, provided that you duplicate
+all of the original copyright notices and associated disclaimers. At
+your discretion, such verbatim copies may or may not include a
+Compiled form of the Package.
+
+(3) You may apply any bug fixes, portability changes, and other
+modifications made available from the Copyright Holder. The resulting
+Package will still be considered the Standard Version, and as such
+will be subject to the Original License.
+
+
+Distribution of Modified Versions of the Package as Source
+
+(4) You may Distribute your Modified Version as Source (either gratis
+or for a Distributor Fee, and with or without a Compiled form of the
+Modified Version) provided that you clearly document how it differs
+from the Standard Version, including, but not limited to, documenting
+any non-standard features, executables, or modules, and provided that
+you do at least ONE of the following:
+
+ (a) make the Modified Version available to the Copyright Holder
+ of the Standard Version, under the Original License, so that the
+ Copyright Holder may include your modifications in the Standard
+ Version.
+
+ (b) ensure that installation of your Modified Version does not
+ prevent the user installing or running the Standard Version. In
+ addition, the Modified Version must bear a name that is different
+ from the name of the Standard Version.
+
+ (c) allow anyone who receives a copy of the Modified Version to
+ make the Source form of the Modified Version available to others
+ under
+
+ (i) the Original License or
+
+ (ii) a license that permits the licensee to freely copy,
+ modify and redistribute the Modified Version using the same
+ licensing terms that apply to the copy that the licensee
+ received, and requires that the Source form of the Modified
+ Version, and of any works derived from it, be made freely
+ available in that license fees are prohibited but Distributor
+ Fees are allowed.
+
+
+Distribution of Compiled Forms of the Standard Version
+or Modified Versions without the Source
+
+(5) You may Distribute Compiled forms of the Standard Version without
+the Source, provided that you include complete instructions on how to
+get the Source of the Standard Version. Such instructions must be
+valid at the time of your distribution. If these instructions, at any
+time while you are carrying out such distribution, become invalid, you
+must provide new instructions on demand or cease further distribution.
+If you provide valid instructions or cease distribution within thirty
+days after you become aware that the instructions are invalid, then
+you do not forfeit any of your rights under this license.
+
+(6) You may Distribute a Modified Version in Compiled form without
+the Source, provided that you comply with Section 4 with respect to
+the Source of the Modified Version.
+
+
+Aggregating or Linking the Package
+
+(7) You may aggregate the Package (either the Standard Version or
+Modified Version) with other packages and Distribute the resulting
+aggregation provided that you do not charge a licensing fee for the
+Package. Distributor Fees are permitted, and licensing fees for other
+components in the aggregation are permitted. The terms of this license
+apply to the use and Distribution of the Standard or Modified Versions
+as included in the aggregation.
+
+(8) You are permitted to link Modified and Standard Versions with
+other works, to embed the Package in a larger work of your own, or to
+build stand-alone binary or bytecode versions of applications that
+include the Package, and Distribute the result without restriction,
+provided the result does not expose a direct interface to the Package.
+
+
+Items That are Not Considered Part of a Modified Version
+
+(9) Works (including, but not limited to, modules and scripts) that
+merely extend or make use of the Package, do not, by themselves, cause
+the Package to be a Modified Version. In addition, such works are not
+considered parts of the Package itself, and are not subject to the
+terms of this license.
+
+
+General Provisions
+
+(10) Any use, modification, and distribution of the Standard or
+Modified Versions is governed by this Artistic License. By using,
+modifying or distributing the Package, you accept this license. Do not
+use, modify, or distribute the Package, if you do not accept this
+license.
+
+(11) If your Modified Version has been derived from a Modified
+Version made by someone other than you, you are nevertheless required
+to ensure that your Modified Version complies with the requirements of
+this license.
+
+(12) This license does not grant you the right to use any trademark,
+service mark, tradename, or logo of the Copyright Holder.
+
+(13) This license includes the non-exclusive, worldwide,
+free-of-charge patent license to make, have made, use, offer to sell,
+sell, import and otherwise transfer the Package with respect to any
+patent claims licensable by the Copyright Holder that are necessarily
+infringed by the Package. If you institute patent litigation
+(including a cross-claim or counterclaim) against any party alleging
+that the Package constitutes direct or contributory patent
+infringement, then this Artistic License to you shall terminate on the
+date that such litigation is filed.
+
+(14) Disclaimer of Warranty:
+THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
+IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
+LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+[End of LICENSE.txt]
+
+
diff --git a/web/socialcalc-3.js b/web/socialcalc-3.js
new file mode 100644
index 0000000..e334f34
--- /dev/null
+++ b/web/socialcalc-3.js
@@ -0,0 +1,5697 @@
+//
+// The main SocialCalc code module of the SocialCalc package
+//
+/*
+// (c) Copyright 2008 Socialtext, Inc.
+// All Rights Reserved.
+//
+// The contents of this file are subject to the Artistic License 2.0; you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at http://socialcalc.org/licenses/al-20/.
+//
+// Some of the other files in the SocialCalc package are licensed under
+// different licenses. Please note the licenses of the modules you use.
+//
+// Code History:
+//
+// Initially coded by Dan Bricklin of Software Garden, Inc., for Socialtext, Inc.
+// Based in part on the SocialCalc 1.1.0 code written in Perl.
+// The SocialCalc 1.1.0 code was:
+// Portions (c) Copyright 2005, 2006, 2007 Software Garden, Inc.
+// All Rights Reserved.
+// Portions (c) Copyright 2007 Socialtext, Inc.
+// All Rights Reserved.
+// The Perl SocialCalc started as modifications to the wikiCalc(R) program, version 1.0.
+// wikiCalc 1.0 was written by Software Garden, Inc.
+// Unless otherwise specified, referring to "SocialCalc" in comments refers to this
+// JavaScript version of the code, not the SocialCalc Perl code.
+//
+*/
+
+/*
+
+**** Overview ****
+
+This is the beginning of a library of routines for displaying and editing spreadsheet
+data in a browser. The HTML that includes this does not need to have anything
+specific to the spreadsheet or editor already present -- everything is dynamically
+added to the DOM by this code, including the rendered sheet and any editing controls.
+
+The library has a few parts. This is the main SocialCalc code module.
+Other parts are the Table Editor module, the Formula module, and the Format Number module.
+Note: The Table Editor module is licensed under a different license than this module.
+
+The class/object style is derived from O'Reilly's JavaScript by Flanagan, 5th Edition,
+section 9.3, page 157.
+
+All of the data, object definitions, functions, etc., are stored as properties of the SocialCalc
+object so as not to clutter up the global variables nor conflict with other names.
+
+A design goal (not tested yet for success) is to make it possible to have more than one
+spreadsheet active on a page, perhaps even open for editing. It is assumed, though, that
+there is only one mouse and one keyboard (a good assumption on most PCs today but not in the
+new "touch and surface world" Apple and Microsoft are working towards).
+
+The testing has been on Windows Firefox (2 and 3),
+Internet Explorer (6 and 7), Opera (9.23 and mainly later), Mac Safari (3.1), and Mac Firefox (2.0.0.6).
+There are small issues with Firefox before 2.0 (cosmetic with drag handles) and larger ones
+with Opera before 9.5 (the Delete key isn't recognized in some cases -- the 9.5 version was still
+in beta and this bug affects other products like GMail, I believe).
+
+The data is stored in a SocialCalc.Sheet object. The data is organized in a form similar to that
+used by SocialCalc 1.1.0. There is a function for converting a normal SocialCalc spreadsheet
+save data string (the spreadsheet part of a SocialCalc data file) into this internal form.
+
+The SocialCalc.RenderContext class provides methods for rendering a table into the DOM representing
+part of the spreadsheet. It is assumed that the spreadsheet could possibly be very large
+and that rendering the whole thing at once could be too time consuming. It is also set up so
+that it might be possible to have some of the sheet data only be loaded on demand (such as by Ajax).
+The rendering can render cells to the right and below the already active area of the spreadsheet
+so that you can scroll to that "clean" area without explicitly doing "add row/column". The class also
+does simple operations such as "scrolling" within that table. The table may optionally include
+row and column headers and may be split into panes. Most of the code assumes any number of panes,
+but only the rightmost pane has scrolling code. In normal operation there would be one or two
+panes horizontally and vertically. The panes may start on any row/column, though a given row/column
+should only appear in one pane at a time (not all code enforces this, yet).
+
+The RenderContext is designed to be rendered as part of a SocialCalc.TableEditor. The TableEditor
+includes the spreadsheet grid as well as scrollbars, pane sliders, and (eventually) editing controls.
+The layout is dynamic and may be recomputed on the fly, such as in response to resizing the browser
+window.
+
+The scrollbars and pane sliders are created using SocialCalc.TableControl objects. These in turn
+make use of Dragging, ToolTip, Button, and MouseWheel functions.
+
+The keyboard input is handled by keyboard code.
+
+There are also some helper routines.
+
+More comments yet to come...
+
+*/
+
+
+var SocialCalc;
+if (!SocialCalc) SocialCalc = {};
+
+// *************************************
+//
+// Shared values
+//
+// These are "global" values shared by the classes, including default settings
+//
+// *************************************
+
+// Callbacks
+
+SocialCalc.Callbacks = {
+
+ // The next two are used by SocialCalc.format_text_for_display
+
+ // The function to expand wiki text - should be set if you want wikitext expansion
+ // The form is: expand_wiki(displayvalue, sheetobj, linkstyle, valueformat)
+ // valueformat is text-wiki followed by optional sub-formats, e.g., text-wikipagelink
+
+ expand_wiki: null,
+
+ expand_markup: function(displayvalue, sheetobj, linkstyle) // the old function to expand wiki text - may be replaced
+ {return SocialCalc.default_expand_markup(displayvalue, sheetobj, linkstyle);},
+
+ // MakePageLink is used to create the href for a link to another "page"
+ // The form is: MakePageLink(pagename, workspacename, linktyle, valueformat), returns string
+
+ MakePageLink: null,
+
+ // NormalizeSheetName is used to make different variations of sheetnames use the same cache slot
+
+ NormalizeSheetName: null // use default - lowercase
+
+ };
+
+// Shared flags
+
+ // none at present
+
+
+// *************************************
+//
+// Cell class:
+//
+// *************************************
+
+//
+// Class SocialCalc.Cell
+//
+// Usage: var s = new SocialCalc.Cell(coord);
+//
+// Cell attributes include:
+//
+// coord: the column/row as a string, e.g., "A1"
+// datavalue: the value to be used for computation and formatting for display,
+// string or numeric (tolerant of numbers stored as strings)
+// datatype: if present, v=numeric value, t=text value, f=formula,
+// or c=constant that is not a simple number (like "$1.20")
+// formula: if present, the formula (without leading "=") for computation or the constant
+// valuetype: first char is main type, the following are sub-types.
+// Main types are b=blank cell, n=numeric, t=text, e=error
+// Examples of using sub-types would be "nt" for a numeric time value, "n$" for currency, "nl" for logical
+// displayvalue: if present, rendered version of datavalue with formatting attributes applied
+// parseinfo: if present, cached parsed version of formula
+//
+// The following optional values, if present, are mainly used in rendering, overriding defaults:
+//
+// bt, br, bb, bl: number of border's definition
+// layout: layout (vertical alignment, padding) definition number
+// font: font definition number
+// color: text color definition number
+// bgcolor: background color definition number
+// cellformat: cell format (horizontal alignment) definition number
+// nontextvalueformat: custom format definition number for non-text values, e.g., numbers
+// textvalueformat: custom format definition number for text values
+// colspan, rowspan: number of cells to span for merged cells (only on main cell)
+// cssc: custom css classname for cell, as text (no special chars)
+// csss: custom css style definition
+// mod: modification allowed flag "y" if present
+// comment: cell comment string
+//
+
+SocialCalc.Cell = function(coord) {
+
+ this.coord = coord;
+ this.datavalue = "";
+ this.datatype = null;
+ this.formula = "";
+ this.valuetype = "b";
+
+ }
+
+// The types of cell properties
+//
+// Type 1: Base, Type 2: Attribute, Type 3: Special (e.g., displaystring, parseinfo)
+
+SocialCalc.CellProperties = {
+ coord: 1, datavalue: 1, datatype: 1, formula: 1, valuetype: 1, errors: 1, comment: 1,
+ bt: 2, br: 2, bb: 2, bl: 2, layout: 2, font: 2, color: 2, bgcolor: 2,
+ cellformat: 2, nontextvalueformat: 2, textvalueformat: 2, colspan: 2, rowspan: 2,
+ cssc: 2, csss: 2, mod: 2,
+ displaystring: 3, // used to cache rendered HTML of cell contents
+ parseinfo: 3, // used to cache parsed formulas
+ hcolspan: 3, hrowspan: 3 // spans taking hidden cols/rows into account (!!! NOT YET !!!)
+ };
+
+SocialCalc.CellPropertiesTable = {
+ bt: "borderstyle", br: "borderstyle", bb: "borderstyle", bl: "borderstyle",
+ layout: "layout", font: "font", color: "color", bgcolor: "color",
+ cellformat: "cellformat", nontextvalueformat: "valueformat", textvalueformat: "valueformat"
+ };
+
+// *************************************
+//
+// Sheet class:
+//
+// *************************************
+
+//
+// Class SocialCalc.Sheet
+//
+// Usage: var s = new SocialCalc.Sheet();
+//
+
+SocialCalc.Sheet = function() {
+
+ SocialCalc.ResetSheet(this);
+
+ // Set other values:
+ //
+ // sheet.statuscallback(data, status, arg, this.statuscallbackparams) is called
+ // during recalc and commands.
+ //
+ // During recalc, data is the current recalcdata.
+ // The values for status and the corresponding arg are:
+ //
+ // calcorder, {coord: coord, total: celllist length, count: count} [0 or more times per recalc]
+ // calccheckdone, calclist length [once per recalc]
+ // calcstep, {coord: coord, total: calclist length, count: count} [0 or more times per recalc]
+ // calcloading, {sheetname: name-of-sheet}
+ // calcserverfunc, {funcname: name-of-function, coord: coord, total: calclist length, count: count}
+ // calcfinished, time in milliseconds [once per recalc]
+ //
+ // During commands, data is SocialCalc.SheetCommandInfo.
+ // These values for status and arg are:
+ //
+ // cmdstart, cmdstr
+ // cmdend
+ //
+
+ this.statuscallback = null; // routine called with cmdstart, calcstart, etc., status and args:
+ // sheet.statuscallback(data, status, arg, params)
+ this.statuscallbackparams = null; // parameters passed to that routine
+
+ }
+
+//
+// SocialCalc.ResetSheet(sheet)
+//
+// Resets (and/or initializes) sheet data values.
+//
+
+SocialCalc.ResetSheet = function(sheet, reload) {
+
+ // properties:
+
+ sheet.cells = {}; // at least one for each non-blank cell: coord: cell-object
+ sheet.attribs = // sheet attributes
+ {
+ lastcol: 1,
+ lastrow: 1,
+ defaultlayout: 0
+ };
+ sheet.rowattribs =
+ {
+ hide: {}, // access by row number
+ height: {}
+ };
+ sheet.colattribs =
+ {
+ width: {}, // access by col name
+ hide: {}
+ };
+ sheet.names={}; // Each is: {desc: "optional description", definition: "B5, A1:B7, or =formula"}
+ sheet.layouts=[];
+ sheet.layouthash={};
+ sheet.fonts=[];
+ sheet.fonthash={};
+ sheet.colors=[];
+ sheet.colorhash={};
+ sheet.borderstyles=[];
+ sheet.borderstylehash={};
+ sheet.cellformats=[];
+ sheet.cellformathash={};
+ sheet.valueformats=[];
+ sheet.valueformathash={};
+
+ sheet.copiedfrom = ""; // if a range, then this was loaded from a saved range as clipboard content
+
+ sheet.changes = new SocialCalc.UndoStack();
+
+ sheet.renderneeded = false;
+
+ sheet.changedrendervalues = true; // if true, spans and/or fonts have changed (set by ExecuteSheetCommand & GetStyle)
+
+ sheet.recalcchangedavalue = false; // true if a recalc resulted in a change to a cell's calculated value
+
+ }
+
+// Methods:
+
+SocialCalc.Sheet.prototype.ResetSheet = function() {SocialCalc.ResetSheet(this);};
+SocialCalc.Sheet.prototype.AddCell = function(newcell) {return this.cells[newcell.coord]=newcell;};
+SocialCalc.Sheet.prototype.GetAssuredCell = function(coord) {
+ return this.cells[coord] || this.AddCell(new SocialCalc.Cell(coord));
+ };
+SocialCalc.Sheet.prototype.ParseSheetSave = function(savedsheet) {SocialCalc.ParseSheetSave(savedsheet,this);};
+SocialCalc.Sheet.prototype.CellFromStringParts = function(cell, parts, j) {return SocialCalc.CellFromStringParts(this, cell, parts, j);};
+SocialCalc.Sheet.prototype.CreateSheetSave = function(range, canonicalize) {return SocialCalc.CreateSheetSave(this, range, canonicalize);};
+SocialCalc.Sheet.prototype.CellToString = function(cell) {return SocialCalc.CellToString(this, cell);};
+SocialCalc.Sheet.prototype.CanonicalizeSheet = function(full) {return SocialCalc.CanonicalizeSheet(this, full);};
+SocialCalc.Sheet.prototype.EncodeCellAttributes = function(coord) {return SocialCalc.EncodeCellAttributes(this, coord);};
+SocialCalc.Sheet.prototype.EncodeSheetAttributes = function() {return SocialCalc.EncodeSheetAttributes(this);};
+SocialCalc.Sheet.prototype.DecodeCellAttributes = function(coord, attribs, range) {return SocialCalc.DecodeCellAttributes(this, coord, attribs, range);};
+SocialCalc.Sheet.prototype.DecodeSheetAttributes = function(attribs) {return SocialCalc.DecodeSheetAttributes(this, attribs);};
+
+//3 points should be noted here-
+//1. notSendOverMesh is used to check whether the command is called while receiving the string from other xo or by the browser itself,
+//in the former case the value of notSendOverMesh should be true and the string will not be sent over the mesh
+//
+//2. In case it gives error, then might be req to place a condn while calling the original ScheduleSheetCommands fn whether a true or a false is to be sent
+//
+//3. In case it gives error, might be req to pass an argument notSendOverMesh from all the fns calling it from the browser with the value false
+try {SocialCalc.Sheet.prototype.ScheduleSheetCommands = function(cmd, saveundo, notSendOverMesh) {try {return SocialCalc.ScheduleSheetCommands(this, cmd, saveundo,notSendOverMesh);}catch(err){window.XO.errorMessage='here lies the problem'+err;alert('here lies the problem'+err);}}; }//end of try
+catch(err)
+{alert('here lies the problem'+err)}SocialCalc.Sheet.prototype.SheetUndo = function() {return SocialCalc.SheetUndo(this);};
+SocialCalc.Sheet.prototype.SheetRedo = function() {return SocialCalc.SheetRedo(this);};
+SocialCalc.Sheet.prototype.CreateAuditString = function() {return SocialCalc.CreateAuditString(this);};
+SocialCalc.Sheet.prototype.GetStyleNum = function(atype, style) {return SocialCalc.GetStyleNum(this, atype, style);};
+SocialCalc.Sheet.prototype.GetStyleString = function(atype, num) {return SocialCalc.GetStyleString(this, atype, num);};
+SocialCalc.Sheet.prototype.RecalcSheet = function() {return SocialCalc.RecalcSheet(this);};
+
+//
+// Sheet save format:
+//
+// linetype:param1:param2:...
+//
+// Linetypes are:
+//
+// version:versionname - version of this format. Currently 1.4.
+//
+// cell:coord:type:value...:type:value... - Types are as follows:
+//
+// v:value - straight numeric value
+// t:value - straight text/wiki-text in cell, encoded to handle \, :, newlines
+// vt:fulltype:value - value with value type/subtype
+// vtf:fulltype:value:formulatext - formula resulting in value with value type/subtype, value and text encoded
+// vtc:fulltype:value:valuetext - formatted text constant resulting in value with value type/subtype, value and text encoded
+// vf:fvalue:formulatext - formula resulting in value, value and text encoded (obsolete: only pre format version 1.1)
+// fvalue - first char is "N" for numeric value, "T" for text value, "H" for HTML value, rest is the value
+// e:errortext - Error text. Non-blank means formula parsing/calculation results in error.
+// b:topborder#:rightborder#:bottomborder#:leftborder# - border# in sheet border list or blank if none
+// l:layout# - number in cell layout list
+// f:font# - number in sheet fonts list
+// c:color# - sheet color list index for text
+// bg:color# - sheet color list index for background color
+// cf:format# - sheet cell format number for explicit format (align:left, etc.)
+// cvf:valueformat# - sheet cell value format number (obsolete: only pre format v1.2)
+// tvf:valueformat# - sheet cell text value format number
+// ntvf:valueformat# - sheet cell non-text value format number
+// colspan:numcols - number of columns spanned in merged cell
+// rowspan:numrows - number of rows spanned in merged cell
+// cssc:classname - name of CSS class to be used for cell when published instead of one calculated here
+// csss:styletext - explicit CSS style information, encoded to handle :, etc.
+// mod:allow - if "y" allow modification of cell for live "view" recalc
+// comment:value - encoded text of comment for this cell (added in v1.5)
+//
+// col:
+// w:widthval - number, "auto" (no width in <col> tag), number%, or blank (use default)
+// hide: - yes/no, no is assumed if missing
+// row:
+// hide - yes/no, no is assumed if missing
+//
+// sheet:
+// c:lastcol - number
+// r:lastrow - number
+// w:defaultcolwidth - number, "auto", number%, or blank (default->80)
+// h:defaultrowheight - not used
+// tf:format# - cell format number for sheet default for text values
+// ntf:format# - cell format number for sheet default for non-text values (i.e., numbers)
+// layout:layout# - default cell layout number in cell layout list
+// font:font# - default font number in sheet font list
+// vf:valueformat# - default number value format number in sheet valueformat list (obsolete: only pre format version 1.2)
+// ntvf:valueformat# - default non-text (number) value format number in sheet valueformat list
+// tvf:valueformat# - default text value format number in sheet valueformat list
+// color:color# - default number for text color in sheet color list
+// bgcolor:color# - default number for background color in sheet color list
+// circularreferencecell:coord - cell coord with a circular reference
+// recalc:value - on/off (on is default). If not "off", appropriate changes to the sheet cause a recalc
+// needsrecalc:value - yes/no (no is default). If "yes", formula values are not up to date
+//
+// name:name:description:value - name definition, name in uppercase, with value being "B5", "A1:B7", or "=formula";
+// description and value are encoded.
+// font:fontnum:value - text of font definition (style weight size family) for font fontnum
+// "*" for "style weight", size, or family, means use default (first look to sheet, then builtin)
+// color:colornum:rgbvalue - text of color definition (e.g., rgb(255,255,255)) for color colornum
+// border:bordernum:value - text of border definition (thickness style color) for border bordernum
+// layout:layoutnum:value - text of vertical alignment and padding style for cell layout layoutnum (* for default):
+// vertical-alignment:vavalue;padding:topval rightval bottomval leftval;
+// cellformat:cformatnum:value - text of cell alignment (left/center/right) for cellformat cformatnum
+// valueformat:vformatnum:value - text of number format (see FormatValueForDisplay) for valueformat vformatnum (changed in v1.2)
+// clipboardrange:upperleftcoord:bottomrightcoord - ignored -- from wikiCalc
+// clipboard:coord:type:value:... - ignored -- from wikiCalc
+//
+// If this is clipboard contents, then there is also information to facilitate pasting:
+//
+// copiedfrom:upperleftcoord:bottomrightcoord - range from which this was copied
+//
+
+// Functions:
+
+SocialCalc.ParseSheetSave = function(savedsheet,sheetobj) {
+
+ var lines=savedsheet.split(/\r\n|\n/);
+ var parts=[];
+ var line;
+ var i, j, t, v, coord, cell, attribs, name;
+ var scc = SocialCalc.Constants;
+
+ for (i=0;i<lines.length;i++) {
+ line=lines[i];
+ parts = line.split(":");
+ switch (parts[0]) {
+ case "cell":
+ cell=sheetobj.GetAssuredCell(parts[1]);
+ j=2;
+ sheetobj.CellFromStringParts(cell, parts, j);
+ break;
+
+ case "col":
+ coord=parts[1];
+ j=2;
+ while (t=parts[j++]) {
+ switch (t) {
+ case "w":
+ sheetobj.colattribs.width[coord]=parts[j++]; // must be text - could be auto or %, etc.
+ break;
+ case "hide":
+ sheetobj.colattribs.hide[coord]=parts[j++];
+ break;
+ default:
+ throw scc.s_pssUnknownColType+" '"+t+"'";
+ break;
+ }
+ }
+ break;
+
+ case "row":
+ coord=parts[1]-0;
+ j=2;
+ while (t=parts[j++]) {
+ switch (t) {
+ case "h":
+ sheetobj.rowattribs.height[coord]=parts[j++]-0;
+ break;
+ case "hide":
+ sheetobj.rowattribs.hide[coord]=parts[j++];
+ break;
+ default:
+ throw scc.s_pssUnknownRowType+" '"+t+"'";
+ break;
+ }
+ }
+ break;
+
+ case "sheet":
+ attribs=sheetobj.attribs;
+ j=1;
+ while (t=parts[j++]) {
+ switch (t) {
+ case "c":
+ attribs.lastcol=parts[j++]-0;
+ break;
+ case "r":
+ attribs.lastrow=parts[j++]-0;
+ break;
+ case "w":
+ attribs.defaultcolwidth=parts[j++]+"";
+ break;
+ case "h":
+ attribs.defaultrowheight=parts[j++]-0;
+ break;
+ case "tf":
+ attribs.defaulttextformat=parts[j++]-0;
+ break;
+ case "ntf":
+ attribs.defaultnontextformat=parts[j++]-0;
+ break;
+ case "layout":
+ attribs.defaultlayout=parts[j++]-0;
+ break;
+ case "font":
+ attribs.defaultfont=parts[j++]-0;
+ break;
+ case "tvf":
+ attribs.defaulttextvalueformat=parts[j++]-0;
+ break;
+ case "ntvf":
+ attribs.defaultnontextvalueformat=parts[j++]-0;
+ break;
+ case "color":
+ attribs.defaultcolor=parts[j++]-0;
+ break;
+ case "bgcolor":
+ attribs.defaultbgcolor=parts[j++]-0;
+ break;
+ case "circularreferencecell":
+ attribs.circularreferencecell=parts[j++];
+ break;
+ case "recalc":
+ attribs.recalc=parts[j++];
+ break;
+ case "needsrecalc":
+ attribs.needsrecalc=parts[j++];
+ break;
+ default:
+ j+=1;
+ break;
+ }
+ }
+ break;
+
+ case "name":
+ name = SocialCalc.decodeFromSave(parts[1]).toUpperCase();
+ sheetobj.names[name] = {desc: SocialCalc.decodeFromSave(parts[2])};
+ sheetobj.names[name].definition = SocialCalc.decodeFromSave(parts[3]);
+ break;
+
+ case "layout":
+ parts=lines[i].match(/^layout\:(\d+)\:(.+)$/); // layouts can have ":" in them
+ sheetobj.layouts[parts[1]-0]=parts[2];
+ sheetobj.layouthash[parts[2]]=parts[1]-0;
+ break;
+
+ case "font":
+ sheetobj.fonts[parts[1]-0]=parts[2];
+ sheetobj.fonthash[parts[2]]=parts[1]-0;
+ break;
+
+ case "color":
+ sheetobj.colors[parts[1]-0]=parts[2];
+ sheetobj.colorhash[parts[2]]=parts[1]-0;
+ break;
+
+ case "border":
+ sheetobj.borderstyles[parts[1]-0]=parts[2];
+ sheetobj.borderstylehash[parts[2]]=parts[1]-0;
+ break;
+
+ case "cellformat":
+ v=SocialCalc.decodeFromSave(parts[2]);
+ sheetobj.cellformats[parts[1]-0]=v;
+ sheetobj.cellformathash[v]=parts[1]-0;
+ break;
+
+ case "valueformat":
+ v=SocialCalc.decodeFromSave(parts[2]);
+ sheetobj.valueformats[parts[1]-0]=v;
+ sheetobj.valueformathash[v]=parts[1]-0;
+ break;
+
+ case "version":
+ break;
+
+ case "copiedfrom":
+ sheetobj.copiedfrom = parts[1]+":"+parts[2];
+ break;
+
+ case "clipboardrange": // in save versions up to 1.3. Ignored.
+ case "clipboard":
+ break;
+
+ case "":
+ break;
+
+ default:
+alert(scc.s_pssUnknownLineType+" '"+parts[0]+"'");
+ throw scc.s_pssUnknownLineType+" '"+parts[0]+"'";
+ break;
+ }
+ parts = null;
+ }
+
+ }
+
+//
+// SocialCalc.CellFromStringParts(sheet, cell, parts, j)
+//
+// Takes string that has been split by ":" in parts, starting at item j,
+// and fills in cell assuming save format.
+//
+
+SocialCalc.CellFromStringParts = function(sheet, cell, parts, j) {
+
+ var cell, t, v;
+
+ while (t=parts[j++]) {
+ switch (t) {
+ case "v":
+ cell.datavalue=SocialCalc.decodeFromSave(parts[j++])-0;
+ cell.datatype="v";
+ cell.valuetype="n";
+ break;
+ case "t":
+ cell.datavalue=SocialCalc.decodeFromSave(parts[j++]);
+ cell.datatype="t";
+ cell.valuetype=SocialCalc.Constants.textdatadefaulttype;
+ break;
+ case "vt":
+ v=parts[j++];
+ cell.valuetype=v;
+ if (v.charAt(0)=="n") {
+ cell.datatype="v";
+ cell.datavalue=SocialCalc.decodeFromSave(parts[j++])-0;
+ }
+ else {
+ cell.datatype="t";
+ cell.datavalue=SocialCalc.decodeFromSave(parts[j++]);
+ }
+ break;
+ case "vtf":
+ v=parts[j++];
+ cell.valuetype=v;
+ if (v.charAt(0)=="n") {
+ cell.datavalue=SocialCalc.decodeFromSave(parts[j++])-0;
+ }
+ else {
+ cell.datavalue=SocialCalc.decodeFromSave(parts[j++]);
+ }
+ cell.formula=SocialCalc.decodeFromSave(parts[j++]);
+ cell.datatype="f";
+ break;
+ case "vtc":
+ v=parts[j++];
+ cell.valuetype=v;
+ if (v.charAt(0)=="n") {
+ cell.datavalue=SocialCalc.decodeFromSave(parts[j++])-0;
+ }
+ else {
+ cell.datavalue=SocialCalc.decodeFromSave(parts[j++]);
+ }
+ cell.formula=SocialCalc.decodeFromSave(parts[j++]);
+ cell.datatype="c";
+ break;
+ case "e":
+ cell.errors=SocialCalc.decodeFromSave(parts[j++]);
+ break;
+ case "b":
+ cell.bt=parts[j++]-0;
+ cell.br=parts[j++]-0;
+ cell.bb=parts[j++]-0;
+ cell.bl=parts[j++]-0;
+ break;
+ case "l":
+ cell.layout=parts[j++]-0;
+ break;
+ case "f":
+ cell.font=parts[j++]-0;
+ break;
+ case "c":
+ cell.color=parts[j++]-0;
+ break;
+ case "bg":
+ cell.bgcolor=parts[j++]-0;
+ break;
+ case "cf":
+ cell.cellformat=parts[j++]-0;
+ break;
+ case "ntvf":
+ cell.nontextvalueformat=parts[j++]-0;
+ break;
+ case "tvf":
+ cell.textvalueformat=parts[j++]-0;
+ break;
+ case "colspan":
+ cell.colspan=parts[j++]-0;
+ break;
+ case "rowspan":
+ cell.rowspan=parts[j++]-0;
+ break;
+ case "cssc":
+ cell.cssc=parts[j++];
+ break;
+ case "csss":
+ cell.csss=SocialCalc.decodeFromSave(parts[j++]);
+ break;
+ case "mod":
+ j+=1;
+ break;
+ case "comment":
+ cell.comment=SocialCalc.decodeFromSave(parts[j++]);
+ break;
+ default:
+ throw SocialCalc.Constants.s_cfspUnknownCellType+" '"+t+"'";
+ break;
+ }
+ }
+
+ }
+
+
+SocialCalc.sheetfields = ["defaultrowheight", "defaultcolwidth", "circularreferencecell", "recalc", "needsrecalc"];
+SocialCalc.sheetfieldsshort = ["h", "w", "circularreferencecell", "recalc", "needsrecalc"];
+
+SocialCalc.sheetfieldsxlat = ["defaulttextformat", "defaultnontextformat",
+ "defaulttextvalueformat", "defaultnontextvalueformat",
+ "defaultcolor", "defaultbgcolor", "defaultfont", "defaultlayout"];
+SocialCalc.sheetfieldsxlatshort = ["tf", "ntf", "tvf", "ntvf", "color", "bgcolor", "font", "layout"];
+SocialCalc.sheetfieldsxlatxlt = ["cellformat", "cellformat", "valueformat", "valueformat",
+ "color", "color", "font", "layout"];
+
+//
+// sheetstr = SocialCalc.CreateSheetSave(sheetobj, range, canonicalize)
+//
+// Creates a text representation of the sheetobj data.
+// If the range is present then only those cells are saved
+// (as clipboard data with "copiedfrom" set).
+//
+
+SocialCalc.CreateSheetSave = function(sheetobj, range, canonicalize) {
+
+ var cell, cr1, cr2, row, col, coord, attrib, line, value, formula, i, t, r, b, l, name, blanklen;
+ var result=[];
+
+ var prange;
+
+ sheetobj.CanonicalizeSheet(canonicalize || SocialCalc.Constants.doCanonicalizeSheet);
+ var xlt = sheetobj.xlt;
+
+ if (range) {
+ prange = SocialCalc.ParseRange(range);
+ }
+ else {
+ prange = {cr1: {row: 1, col:1},
+ cr2: {row: xlt.maxrow, col: xlt.maxcol}};
+ }
+ cr1 = prange.cr1;
+ cr2 = prange.cr2;
+
+ result.push("version:1.5");
+
+ for (row=cr1.row; row <= cr2.row; row++) {
+ for (col=cr1.col; col <= cr2.col; col++) {
+ coord = SocialCalc.crToCoord(col, row);
+ cell=sheetobj.cells[coord];
+ if (!cell) continue;
+ line=sheetobj.CellToString(cell);
+ if (line.length==0) continue; // ignore completely empty cells
+ line="cell:"+coord+line;
+ result.push(line);
+ }
+ }
+
+ for (col=1; col <= xlt.maxcol; col++) {
+ coord = SocialCalc.rcColname(col);
+ if (sheetobj.colattribs.width[coord])
+ result.push("col:"+coord+":w:"+sheetobj.colattribs.width[coord]);
+ if (sheetobj.colattribs.hide[coord])
+ result.push("col:"+coord+":hide:"+sheetobj.colattribs.hide[coord]);
+ }
+
+ for (row=1; row <= xlt.maxrow; row++) {
+ if (sheetobj.rowattribs.height[row])
+ result.push("row:"+row+":h:"+sheetobj.rowattribs.height[row]);
+ if (sheetobj.rowattribs.hide[row])
+ result.push("row:"+row+":hide:"+sheetobj.rowattribs.hide[row]);
+ }
+
+ line="sheet:c:"+xlt.maxcol+":r:"+xlt.maxrow;
+
+ for (i=0; i<SocialCalc.sheetfields.length; i++) { // non-xlated values
+ value = SocialCalc.encodeForSave(sheetobj.attribs[SocialCalc.sheetfields[i]]);
+ if (value) line+=":"+SocialCalc.sheetfieldsshort[i]+":"+value;
+ }
+ for (i=0; i<SocialCalc.sheetfieldsxlat.length; i++) { // xlated values
+ value = sheetobj.attribs[SocialCalc.sheetfieldsxlat[i]];
+ if (value) line+=":"+SocialCalc.sheetfieldsxlatshort[i]+":"+xlt[SocialCalc.sheetfieldsxlatxlt[i]+"sxlat"][value];
+ }
+
+ result.push(line);
+
+ for (i=1;i<xlt.newborderstyles.length;i++) {
+ result.push("border:"+i+":"+xlt.newborderstyles[i]);
+ }
+
+ for (i=1;i<xlt.newcellformats.length;i++) {
+ result.push("cellformat:"+i+":"+SocialCalc.encodeForSave(xlt.newcellformats[i]));
+ }
+
+ for (i=1;i<xlt.newcolors.length;i++) {
+ result.push("color:"+i+":"+xlt.newcolors[i]);
+ }
+
+ for (i=1;i<xlt.newfonts.length;i++) {
+ result.push("font:"+i+":"+xlt.newfonts[i]);
+ }
+
+ for (i=1;i<xlt.newlayouts.length;i++) {
+ result.push("layout:"+i+":"+xlt.newlayouts[i]);
+ }
+
+ for (i=1;i<xlt.newvalueformats.length;i++) {
+ result.push("valueformat:"+i+":"+SocialCalc.encodeForSave(xlt.newvalueformats[i]));
+ }
+
+ for (i=0; i<xlt.namesorder.length; i++) {
+ name = xlt.namesorder[i];
+ result.push("name:"+SocialCalc.encodeForSave(name).toUpperCase()+":"+
+ SocialCalc.encodeForSave(sheetobj.names[name].desc)+":"+
+ SocialCalc.encodeForSave(sheetobj.names[name].definition));
+ }
+
+ if (range) {
+ result.push("copiedfrom:"+SocialCalc.crToCoord(cr1.col, cr1.row)+":"+
+ SocialCalc.crToCoord(cr2.col, cr2.row));
+ }
+
+ result.push(""); // one extra to get extra \n
+
+ delete sheetobj.xlt; // clean up
+
+ return result.join("\n");
+ }
+
+//
+// line = SocialCalc.CellToString(sheet, cell)
+//
+
+SocialCalc.CellToString = function(sheet, cell) {
+
+ var cell, line, value, formula, t, r, b, l, xlt;
+
+ line = "";
+
+ if (!cell) return line;
+
+ value = SocialCalc.encodeForSave(cell.datavalue);
+ if (cell.datatype=="v") {
+ if (cell.valuetype=="n") line += ":v:"+value;
+ else line += ":vt:"+cell.valuetype+":"+value;
+ }
+ else if (cell.datatype=="t") {
+ if (cell.valuetype==SocialCalc.Constants.textdatadefaulttype)
+ line += ":t:"+value;
+ else line += ":vt:"+cell.valuetype+":"+value;
+ }
+ else {
+ formula = SocialCalc.encodeForSave(cell.formula);
+ if (cell.datatype=="f") {
+ line += ":vtf:"+cell.valuetype+":"+value+":"+formula;
+ }
+ else if (cell.datatype=="c") {
+ line += ":vtc:"+cell.valuetype+":"+value+":"+formula;
+ }
+ }
+ if (cell.errors) {
+ line += ":e:"+SocialCalc.encodeForSave(cell.errors);
+ }
+ t = cell.bt || "";
+ r = cell.br || "";
+ b = cell.bb || "";
+ l = cell.bl || "";
+
+ if (sheet.xlt) { // if have canonical save info
+ xlt = sheet.xlt;
+ if (t || r || b || l)
+ line += ":b:"+xlt.borderstylesxlat[t||0]+":"+xlt.borderstylesxlat[r||0]+":"+xlt.borderstylesxlat[b||0]+":"+xlt.borderstylesxlat[l||0];
+ if (cell.layout) line += ":l:"+xlt.layoutsxlat[cell.layout];
+ if (cell.font) line += ":f:"+xlt.fontsxlat[cell.font];
+ if (cell.color) line += ":c:"+xlt.colorsxlat[cell.color];
+ if (cell.bgcolor) line += ":bg:"+xlt.colorsxlat[cell.bgcolor];
+ if (cell.cellformat) line += ":cf:"+xlt.cellformatsxlat[cell.cellformat];
+ if (cell.textvalueformat) line += ":tvf:"+xlt.valueformatsxlat[cell.textvalueformat];
+ if (cell.nontextvalueformat) line += ":ntvf:"+xlt.valueformatsxlat[cell.nontextvalueformat];
+ }
+ else {
+ if (t || r || b || l)
+ line += ":b:"+t+":"+r+":"+b+":"+l;
+ if (cell.layout) line += ":l:"+cell.layout;
+ if (cell.font) line += ":f:"+cell.font;
+ if (cell.color) line += ":c:"+cell.color;
+ if (cell.bgcolor) line += ":bg:"+cell.bgcolor;
+ if (cell.cellformat) line += ":cf:"+cell.cellformat;
+ if (cell.textvalueformat) line += ":tvf:"+cell.textvalueformat;
+ if (cell.nontextvalueformat) line += ":ntvf:"+cell.nontextvalueformat;
+ }
+ if (cell.colspan) line += ":colspan:"+cell.colspan;
+ if (cell.rowspan) line += ":rowspan:"+cell.rowspan;
+ if (cell.cssc) line += ":cssc:"+cell.cssc;
+ if (cell.csss) line += ":csss:"+SocialCalc.encodeForSave(cell.csss);
+ if (cell.mod) line += ":mod:"+cell.mod;
+ if (cell.comment) line += ":comment:"+SocialCalc.encodeForSave(cell.comment);
+
+ return line;
+
+ }
+
+//
+// SocialCalc.CanonicalizeSheet(sheetobj, full)
+//
+// Goes through the sheet and fills in sheetobj.xlt with the following:
+//
+// .maxrow, .maxcol - lastrow and lastcol are as small as possible
+// .newlayouts - new version of sheetobj.layouts without unused ones and all in ascending order
+// .layoutsxlat - maps old layouts index to new one
+// same ".new" and ".xlat" for fonts, colors, borderstyles, cell and value formats
+// .namesorder - array with names sorted
+//
+// If full or SocialCalc.Constants.doCanonicalizeSheet are not true, then the values will leave things unchanged (to save time, etc.)
+//
+// sheetobj.xlt should be deleted when you are finished using it
+//
+
+SocialCalc.CanonicalizeSheet = function(sheetobj, full) {
+
+ var l, coord, cr, cell, filled, an, a, newa, newxlat, used, ahash, i, v;
+ var maxrow = 0;
+ var maxcol = 0;
+ var alist = ["borderstyle", "cellformat", "color", "font", "layout", "valueformat"];
+
+ var xlt = {};
+
+ xlt.namesorder = []; // always return a sorted list
+ for (a in sheetobj.names) {
+ xlt.namesorder.push(a);
+ }
+ xlt.namesorder.sort();
+
+ if (!SocialCalc.Constants.doCanonicalizeSheet || !full) { // return make-no-changes values if not wanted
+ for (an=0; an<alist.length; an++) {
+ a = alist[an];
+ xlt["new"+a+"s"] = sheetobj[a+"s"];
+ l = sheetobj[a+"s"].length;
+ newxlat = new Array(l);
+ newxlat[0] = "";
+ for (i=1; i<l; i++) {
+ newxlat[i] = i;
+ }
+ xlt[a+"sxlat"] = newxlat;
+ }
+
+ xlt.maxrow = sheetobj.attribs.lastrow;
+ xlt.maxcol = sheetobj.attribs.lastcol;
+
+ sheetobj.xlt = xlt;
+
+ return;
+ }
+
+ for (an=0; an<alist.length; an++) {
+ a = alist[an];
+ xlt[a+"sUsed"] = {};
+ }
+
+ var colorsUsed = xlt.colorsUsed;
+ var borderstylesUsed = xlt.borderstylesUsed;
+ var fontsUsed = xlt.fontsUsed;
+ var layoutsUsed = xlt.layoutsUsed;
+ var cellformatsUsed = xlt.cellformatsUsed;
+ var valueformatsUsed = xlt.valueformatsUsed;
+
+ for (coord in sheetobj.cells) { // check all cells to see which values are used
+ cr = SocialCalc.coordToCr(coord);
+ cell = sheetobj.cells[coord];
+ filled = false;
+
+ if (cell.valuetype && cell.valuetype!="b") filled = true;
+
+ if (cell.color) {
+ colorsUsed[cell.color] = 1;
+ filled = true;
+ }
+
+ if (cell.bgcolor) {
+ colorsUsed[cell.bgcolor] = 1;
+ filled = true;
+ }
+
+ if (cell.bt) {
+ borderstylesUsed[cell.bt] = 1;
+ filled = true;
+ }
+ if (cell.br) {
+ borderstylesUsed[cell.br] = 1;
+ filled = true;
+ }
+ if (cell.bb) {
+ borderstylesUsed[cell.bb] = 1;
+ filled = true;
+ }
+ if (cell.bl) {
+ borderstylesUsed[cell.bl] = 1;
+ filled = true;
+ }
+
+ if (cell.layout) {
+ layoutsUsed[cell.layout] = 1;
+ filled = true;
+ }
+
+ if (cell.font) {
+ fontsUsed[cell.font] = 1;
+ filled = true;
+ }
+
+ if (cell.cellformat) {
+ cellformatsUsed[cell.cellformat] = 1;
+ filled = true;
+ }
+
+ if (cell.textvalueformat) {
+ valueformatsUsed[cell.textvalueformat] = 1;
+ filled = true;
+ }
+
+ if (cell.nontextvalueformat) {
+ valueformatsUsed[cell.nontextvalueformat] = 1;
+ filled = true;
+ }
+
+ if (filled) {
+ if (cr.row > maxrow) maxrow = cr.row;
+ if (cr.col > maxcol) maxcol = cr.col;
+ }
+ }
+
+ for (i=0; i<SocialCalc.sheetfieldsxlat.length; i++) { // do sheet values, too
+ v = sheetobj.attribs[SocialCalc.sheetfieldsxlat[i]];
+ if (v) {
+ xlt[SocialCalc.sheetfieldsxlatxlt[i]+"sUsed"][v] = 1;
+ }
+ }
+
+ a = {"height": 1, "hide": 1}; // look at explicit row settings
+ for (v in a) {
+ for (cr in sheetobj.rowattribs[v]) {
+ if (cr > maxrow) maxrow = cr;
+ }
+ }
+ a = {"hide": 1, "width": 1}; // look at explicit col settings
+ for (v in a) {
+ for (coord in sheetobj.colattribs[v]) {
+ cr = SocialCalc.coordToCr(coord+"1");
+ if (cr.col > maxcol) maxcol = cr.col;
+ }
+ }
+
+ for (an=0; an<alist.length; an++) { // go through the attribs we want
+ a = alist[an];
+
+ newa = [];
+ used = xlt[a+"sUsed"];
+ for (v in used) {
+ newa.push(sheetobj[a+"s"][v]);
+ }
+ newa.sort();
+ newa.unshift("");
+
+ newxlat = [""];
+ ahash = sheetobj[a+"hash"];
+
+ for (i=1; i<newa.length; i++) {
+ newxlat[ahash[newa[i]]] = i;
+ }
+
+ xlt[a+"sxlat"] = newxlat;
+ xlt["new"+a+"s"] = newa;
+
+ }
+
+ xlt.maxrow = maxrow || 1;
+ xlt.maxcol = maxcol || 1;
+
+ sheetobj.xlt = xlt; // leave for use by caller
+
+ }
+
+//
+// result = SocialCalc.EncodeCellAttributes(sheet, coord)
+//
+// Returns the cell's attributes in an object, each in the following form:
+//
+// attribname: {def: true/false, val: full-value}
+//
+
+SocialCalc.EncodeCellAttributes = function(sheet, coord) {
+
+ var value, i, b, bb;
+ var result = {};
+
+ var InitAttrib = function(name) {
+ result[name] = {def: true, val: ""};
+ }
+
+ var InitAttribs = function(namelist) {
+ for (var i=0; i<namelist.length; i++) {
+ InitAttrib(namelist[i]);
+ }
+ }
+
+ var SetAttrib = function(name, v) {
+ result[name].def = false;
+ result[name].val = v || "";
+ }
+
+ var SetAttribStar = function(name, v) {
+ if (v=="*") return;
+ result[name].def = false;
+ result[name].val = v;
+ }
+
+ var cell = sheet.GetAssuredCell(coord);
+
+ // cellformat: alignhoriz
+
+ InitAttrib("alignhoriz");
+ if (cell.cellformat) {
+ SetAttrib("alignhoriz", sheet.cellformats[cell.cellformat]);
+ }
+
+ // layout: alignvert, padtop, padright, padbottom, padleft
+
+ InitAttribs(["alignvert", "padtop", "padright", "padbottom", "padleft"]);
+ if (cell.layout) {
+ parts = sheet.layouts[cell.layout].match(/^padding:\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+);vertical-align:\s*(\S+);/);
+ SetAttribStar("padtop", parts[1]);
+ SetAttribStar("padright", parts[2]);
+ SetAttribStar("padbottom", parts[3]);
+ SetAttribStar("padleft", parts[4]);
+ SetAttribStar("alignvert", parts[5]);
+ }
+
+ // font: fontfamily, fontlook, fontsize
+
+ InitAttribs(["fontfamily", "fontlook", "fontsize"]);
+ if (cell.font) {
+ parts = sheet.fonts[cell.font].match(/^(\*|\S+? \S+?) (\S+?) (\S.*)$/);
+ SetAttribStar("fontfamily", parts[3]);
+ SetAttribStar("fontsize", parts[2]);
+ SetAttribStar("fontlook", parts[1]);
+ }
+
+ // color: textcolor
+
+ InitAttrib("textcolor");
+ if (cell.color) {
+ SetAttrib("textcolor", sheet.colors[cell.color]);
+ }
+
+ // bgcolor: bgcolor
+
+ InitAttrib("bgcolor");
+ if (cell.bgcolor) {
+ SetAttrib("bgcolor", sheet.colors[cell.bgcolor]);
+ }
+
+ // formatting: numberformat, textformat
+
+ InitAttribs(["numberformat", "textformat"]);
+ if (cell.nontextvalueformat) {
+ SetAttrib("numberformat", sheet.valueformats[cell.nontextvalueformat]);
+ }
+ if (cell.textvalueformat) {
+ SetAttrib("textformat", sheet.valueformats[cell.textvalueformat]);
+ }
+
+ // merges: colspan, rowspan
+
+ InitAttribs(["colspan", "rowspan"]);
+ SetAttrib("colspan", cell.colspan || 1);
+ SetAttrib("rowspan", cell.rowspan || 1);
+
+ // borders: bXthickness, bXstyle, bXcolor for X = t, r, b, and l
+
+ for (i=0; i<4; i++) {
+ b = "trbl".charAt(i);
+ bb = "b"+b;
+ InitAttrib(bb);
+ SetAttrib(bb, cell[bb] ? sheet.borderstyles[cell[bb]] : "");
+ InitAttrib(bb+"thickness");
+ InitAttrib(bb+"style");
+ InitAttrib(bb+"color");
+ if (cell[bb]) {
+ parts = sheet.borderstyles[cell[bb]].match(/(\S+)\s+(\S+)\s+(\S.+)/);
+ SetAttrib(bb+"thickness", parts[1]);
+ SetAttrib(bb+"style", parts[2]);
+ SetAttrib(bb+"color", parts[3]);
+ }
+ }
+
+ // misc: cssc, csss, mod
+
+ InitAttribs(["cssc", "csss", "mod"]);
+ SetAttrib("cssc", cell.cssc || "");
+ SetAttrib("csss", cell.csss || "");
+ SetAttrib("mod", cell.mod || "n");
+
+ return result;
+
+ }
+
+//
+// result = SocialCalc.EncodeSheetAttributes(sheet)
+//
+// Returns the sheet's attributes in an object, each in the following form:
+//
+// attribname: {def: true/false, val: full-value}
+//
+
+SocialCalc.EncodeSheetAttributes = function(sheet) {
+
+ var value;
+ var attribs = sheet.attribs;
+ var result = {};
+
+ var InitAttrib = function(name) {
+ result[name] = {def: true, val: ""};
+ }
+
+ var InitAttribs = function(namelist) {
+ for (var i=0; i<namelist.length; i++) {
+ InitAttrib(namelist[i]);
+ }
+ }
+
+ var SetAttrib = function(name, v) {
+ result[name].def = false;
+ result[name].val = v || value;
+ }
+
+ var SetAttribStar = function(name, v) {
+ if (v=="*") return;
+ result[name].def = false;
+ result[name].val = v;
+ }
+
+ // sizes: colwidth, rowheight
+
+ InitAttrib("colwidth");
+ if (attribs.defaultcolwidth) {
+ SetAttrib("colwidth", attribs.defaultcolwidth);
+ }
+
+ InitAttrib("rowheight");
+ if (attribs.rowheight) {
+ SetAttrib("rowheight", attribs.defaultrowheight);
+ }
+
+ // cellformat: textalignhoriz, numberalignhoriz
+
+ InitAttrib("textalignhoriz");
+ if (attribs.defaulttextformat) {
+ SetAttrib("textalignhoriz", sheet.cellformats[attribs.defaulttextformat]);
+ }
+
+ InitAttrib("numberalignhoriz");
+ if (attribs.defaultnontextformat) {
+ SetAttrib("numberalignhoriz", sheet.cellformats[attribs.defaultnontextformat]);
+ }
+
+ // layout: alignvert, padtop, padright, padbottom, padleft
+
+ InitAttribs(["alignvert", "padtop", "padright", "padbottom", "padleft"]);
+ if (attribs.defaultlayout) {
+ parts = sheet.layouts[attribs.defaultlayout].match(/^padding:\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+);vertical-align:\s*(\S+);/);
+ SetAttribStar("padtop", parts[1]);
+ SetAttribStar("padright", parts[2]);
+ SetAttribStar("padbottom", parts[3]);
+ SetAttribStar("padleft", parts[4]);
+ SetAttribStar("alignvert", parts[5]);
+ }
+
+ // font: fontfamily, fontlook, fontsize
+
+ InitAttribs(["fontfamily", "fontlook", "fontsize"]);
+ if (attribs.defaultfont) {
+ parts = sheet.fonts[attribs.defaultfont].match(/^(\*|\S+? \S+?) (\S+?) (\S.*)$/);
+ SetAttribStar("fontfamily", parts[3]);
+ SetAttribStar("fontsize", parts[2]);
+ SetAttribStar("fontlook", parts[1]);
+ }
+
+ // color: textcolor
+
+ InitAttrib("textcolor");
+ if (attribs.defaultcolor) {
+ SetAttrib("textcolor", sheet.colors[attribs.defaultcolor]);
+ }
+
+ // bgcolor: bgcolor
+
+ InitAttrib("bgcolor");
+ if (attribs.defaultbgcolor) {
+ SetAttrib("bgcolor", sheet.colors[attribs.defaultbgcolor]);
+ }
+
+ // formatting: numberformat, textformat
+
+ InitAttribs(["numberformat", "textformat"]);
+ if (attribs.defaultnontextvalueformat) {
+ SetAttrib("numberformat", sheet.valueformats[attribs.defaultnontextvalueformat]);
+ }
+ if (attribs.defaulttextvalueformat) {
+ SetAttrib("textformat", sheet.valueformats[attribs.defaulttextvalueformat]);
+ }
+
+ // recalc: recalc
+
+ InitAttrib("recalc");
+ if (attribs.recalc) {
+ SetAttrib("recalc", attribs.recalc);
+ }
+
+ return result;
+
+ }
+
+//
+// cmdstr = SocialCalc.DecodeCellAttributes(sheet, coord, attribs, range)
+//
+// Takes cell attributes in an object, each in the following form:
+//
+// attribname: {def: true/false, val: full-value}
+//
+// and returns the sheet commands to make the actual attributes correspond.
+// Returns a non-null string if any commands are to be executed, null otherwise.
+//
+// If range is provided, the commands are executed on the whole range.
+//
+
+SocialCalc.DecodeCellAttributes = function(sheet, coord, newattribs, range) {
+
+ var value, b, bb;
+
+ var cell = sheet.GetAssuredCell(coord);
+
+ var changed = false;
+
+ var CheckChanges = function(attribname, oldval, cmdname) {
+ var val;
+ if (newattribs[attribname]) {
+ if (newattribs[attribname].def) {
+ val = "";
+ }
+ else {
+ val = newattribs[attribname].val;
+ }
+ if (val != (oldval || "")) {
+ DoCmd(cmdname+" "+val);
+ }
+ }
+ }
+
+ var cmdstr = "";
+
+ var DoCmd = function(str) {
+ if (cmdstr) cmdstr += "\n";
+ cmdstr += "set "+(range || coord)+" "+str;
+ changed = true;
+ }
+
+ // cellformat: alignhoriz
+
+ CheckChanges("alignhoriz", sheet.cellformats[cell.cellformat], "cellformat");
+
+ // layout: alignvert, padtop, padright, padbottom, padleft
+
+ if (!newattribs.alignvert.def || !newattribs.padtop.def || !newattribs.padright.def ||
+ !newattribs.padbottom.def || !newattribs.padleft.def) {
+ value = "padding:" +
+ (newattribs.padtop.def ? "* " : newattribs.padtop.val + " ") +
+ (newattribs.padright.def ? "* " : newattribs.padright.val + " ") +
+ (newattribs.padbottom.def ? "* " : newattribs.padbottom.val + " ") +
+ (newattribs.padleft.def ? "*" : newattribs.padleft.val) +
+ ";vertical-align:" +
+ (newattribs.alignvert.def ? "*;" : newattribs.alignvert.val+";");
+ }
+ else {
+ value = "";
+ }
+
+ if (value != (sheet.layouts[cell.layout] || "")) {
+ DoCmd("layout "+value);
+ }
+
+ // font: fontfamily, fontlook, fontsize
+
+ if (!newattribs.fontlook.def || !newattribs.fontsize.def || !newattribs.fontfamily.def) {
+ value =
+ (newattribs.fontlook.def ? "* " : newattribs.fontlook.val + " ") +
+ (newattribs.fontsize.def ? "* " : newattribs.fontsize.val + " ") +
+ (newattribs.fontfamily.def ? "*" : newattribs.fontfamily.val);
+ }
+ else {
+ value = "";
+ }
+
+ if (value != (sheet.fonts[cell.font] || "")) {
+ DoCmd("font "+value);
+ }
+
+ // color: textcolor
+
+ CheckChanges("textcolor", sheet.colors[cell.color], "color");
+
+ // bgcolor: bgcolor
+
+ CheckChanges("bgcolor", sheet.colors[cell.bgcolor], "bgcolor");
+
+ // formatting: numberformat, textformat
+
+ CheckChanges("numberformat", sheet.valueformats[cell.nontextvalueformat], "nontextvalueformat");
+
+ CheckChanges("textformat", sheet.valueformats[cell.textvalueformat], "textvalueformat");
+
+ // merges: colspan, rowspan - NOT HANDLED: IGNORED!
+
+ // borders: bX for X = t, r, b, and l; bXthickness, bXstyle, bXcolor ignored
+
+ for (i=0; i<4; i++) {
+ b = "trbl".charAt(i);
+ bb = "b"+b;
+ CheckChanges(bb, sheet.borderstyles[cell[bb]], bb);
+ }
+
+ // misc: cssc, csss, mod
+
+ CheckChanges("cssc", cell.cssc, "cssc");
+
+ CheckChanges("csss", cell.csss, "csss");
+
+ if (newattribs.mod) {
+ if (newattribs.mod.def) {
+ value = "n";
+ }
+ else {
+ value = newattribs.mod.val;
+ }
+ if (value != (cell.mod || "n")) {
+ if (value=="n") value = ""; // restrict to "y" and "" normally
+ DoCmd("mod "+value);
+ }
+ }
+
+ // if any changes return command(s)
+
+ if (changed) {
+ return cmdstr;
+ }
+ else {
+ return null;
+ }
+
+ }
+
+
+//
+// changed = SocialCalc.DecodeSheetAttributes(sheet, newattribs)
+//
+// Takes sheet attributes in an object, each in the following form:
+//
+// attribname: {def: true/false, val: full-value}
+//
+// and returns the sheet commands to make the actual attributes correspond.
+// Returns a non-null string if any commands were executed, null otherwise.
+//
+
+SocialCalc.DecodeSheetAttributes = function(sheet, newattribs) {
+
+ var value;
+ var attribs = sheet.attribs;
+ var changed = false;
+
+ var CheckChanges = function(attribname, oldval, cmdname) {
+ var val;
+ if (newattribs[attribname]) {
+ if (newattribs[attribname].def) {
+ val = "";
+ }
+ else {
+ val = newattribs[attribname].val;
+ }
+ if (val != (oldval || "")) {
+ DoCmd(cmdname+" "+val);
+ }
+ }
+ }
+
+ var cmdstr = "";
+
+ var DoCmd = function(str) {
+ if (cmdstr) cmdstr += "\n";
+ cmdstr += "set sheet "+str;
+ changed = true;
+ }
+
+ // sizes: colwidth, rowheight
+
+ CheckChanges("colwidth", attribs.defaultcolwidth, "defaultcolwidth");
+
+ CheckChanges("rowheight", attribs.defaultrowheight, "defaultrowheight");
+
+ // cellformat: textalignhoriz, numberalignhoriz
+
+ CheckChanges("textalignhoriz", sheet.cellformats[attribs.defaulttextformat], "defaulttextformat");
+
+ CheckChanges("numberalignhoriz", sheet.cellformats[attribs.defaultnontextformat], "defaultnontextformat");
+
+ // layout: alignvert, padtop, padright, padbottom, padleft
+
+ if (!newattribs.alignvert.def || !newattribs.padtop.def || !newattribs.padright.def ||
+ !newattribs.padbottom.def || !newattribs.padleft.def) {
+ value = "padding:" +
+ (newattribs.padtop.def ? "* " : newattribs.padtop.val + " ") +
+ (newattribs.padright.def ? "* " : newattribs.padright.val + " ") +
+ (newattribs.padbottom.def ? "* " : newattribs.padbottom.val + " ") +
+ (newattribs.padleft.def ? "*" : newattribs.padleft.val) +
+ ";vertical-align:" +
+ (newattribs.alignvert.def ? "*;" : newattribs.alignvert.val+";");
+ }
+ else {
+ value = "";
+ }
+
+ if (value != (sheet.layouts[attribs.defaultlayout] || "")) {
+ DoCmd("defaultlayout "+value);
+ }
+
+ // font: fontfamily, fontlook, fontsize
+
+ if (!newattribs.fontlook.def || !newattribs.fontsize.def || !newattribs.fontfamily.def) {
+ value =
+ (newattribs.fontlook.def ? "* " : newattribs.fontlook.val + " ") +
+ (newattribs.fontsize.def ? "* " : newattribs.fontsize.val + " ") +
+ (newattribs.fontfamily.def ? "*" : newattribs.fontfamily.val);
+ }
+ else {
+ value = "";
+ }
+
+ if (value != (sheet.fonts[attribs.defaultfont] || "")) {
+ DoCmd("defaultfont "+value);
+ }
+
+ // color: textcolor
+
+ CheckChanges("textcolor", sheet.colors[attribs.defaultcolor], "defaultcolor");
+
+ // bgcolor: bgcolor
+
+ CheckChanges("bgcolor", sheet.colors[attribs.defaultbgcolor], "defaultbgcolor");
+
+ // formatting: numberformat, textformat
+
+ CheckChanges("numberformat", sheet.valueformats[attribs.defaultnontextvalueformat], "defaultnontextvalueformat");
+
+ CheckChanges("textformat", sheet.valueformats[attribs.defaulttextvalueformat], "defaulttextvalueformat");
+
+ // recalc: recalc
+
+ CheckChanges("recalc", sheet.attribs.recalc, "recalc");
+
+ // if any changes return command(s)
+
+ if (changed) {
+ return cmdstr;
+ }
+ else {
+ return null;
+ }
+
+ }
+
+// *************************************
+//
+// Sheet command routines
+//
+// *************************************
+
+//
+// SocialCalc.SheetCommandInfo - object with information used during command execution
+//
+
+SocialCalc.SheetCommandInfo = { // only one of these
+
+ sheetobj: null, // sheet being operated on
+ parseobj: null, // SocialCalc.Parse object with the command string, etc.
+ timerobj: null, // used for timeslicing
+ firsttimerdelay: 50, // wait before starting cmds (for Chrome - to give time to update)
+ timerdelay: 1, // wait between slices
+ maxtimeslice: 100, // do another slice after this many milliseconds
+ saveundo: false, // arg for ExecuteSheetCommand
+
+ statuscallback: null, // called during execution
+ statuscallbackparams: null
+
+ };
+
+//
+// SocialCalc.ScheduleSheetCommands
+//
+// statuscallback is called at the beginning (cmdstart) and end (cmdend).
+//
+
+SocialCalc.ScheduleSheetCommands = function(sheet, cmdstr, saveundo, notSendOverMesh) {
+
+ if (notSendOverMesh!=true)
+ { if (window.XO.flagShared==true) //it checks whether the activity is shared till now or not
+ {
+ if (saveundo==true) //to transfer the saveundo thing to the other xo
+ {var saveundostring='true'}
+ else {var saveundostring='false'}
+
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+ var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
+ array = Components.classes["@mozilla.org/array;1"].createInstance(Components.interfaces.nsIMutableArray)
+ var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString)
+ str.data = cmdstr
+ array.appendElement(str, false)
+ var str2 = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString)
+ str2.data = saveundostring
+ array.appendElement(str2, false)
+ observerService.notifyObservers(array,'xo-message2',saveundostring); //this saveundostring is not req to be sent here, any array can be sent
+
+ }//end of smaller if
+ }//end of if
+
+ if (notSendOverMesh==true)
+ {
+ window.XO.errorMessage=window.XO.errorMessage+' reaching in the schedule command thing'
+ }//end of if
+
+try {
+ var sci = SocialCalc.SheetCommandInfo;
+
+ sci.sheetobj = sheet;
+ sci.parseobj = new SocialCalc.Parse(cmdstr);
+ sci.saveundo = saveundo;
+
+ if (sci.sheetobj.statuscallback) { // notify others if requested
+ sheet.statuscallback(sci, "cmdstart", "", sci.sheetobj.statuscallbackparams);
+ }
+
+ if (sci.saveundo) {
+ sci.sheetobj.changes.PushChange(""); // add a step to undo stack
+ }
+
+ sci.timerobj = window.setTimeout(SocialCalc.SheetCommandsTimerRoutine, sci.firsttimerdelay);
+ if (notSendOverMesh==true)
+ {
+
+ //window.XO.errorMessage=window.XO.errorMessage+' successfully executing the command'
+ }//end of if
+ }
+ catch(err)
+ {window.XO.errorMessage=window.XO.errorMessage+' error is in schedule command'+err}
+
+ }
+
+SocialCalc.SheetCommandsTimerRoutine = function() {
+
+ var errortext;
+ var sci = SocialCalc.SheetCommandInfo;
+ var starttime = new Date();
+
+ sci.timerobj = null;
+
+ while (!sci.parseobj.EOF()) { // go through all commands (separated by newlines)
+
+ errortext = SocialCalc.ExecuteSheetCommand(sci.sheetobj, sci.parseobj, sci.saveundo);
+ if (errortext) alert(errortext);
+
+ sci.parseobj.NextLine();
+
+ if (((new Date()) - starttime) >= sci.maxtimeslice) { // if taking too long, give up CPU for a while
+ sci.timerobj = window.setTimeout(SocialCalc.SheetCommandsTimerRoutine, sci.timerdelay);
+ return;
+ }
+ }
+
+ if (sci.sheetobj.statuscallback) { // notify others if requested
+ sci.sheetobj.statuscallback(sci, "cmdend", "", sci.sheetobj.statuscallbackparams);
+ }
+
+ }
+
+
+//
+// errortext = SocialCalc.ExecuteSheetCommand(sheet, cmd, saveundo)
+//
+// cmd is a SocialCalc.Parse object.
+//
+// Executes commands that modify the sheet data.
+// Sets sheet "needsrecalc" as needed.
+// Sets sheet "changedrendervalues" as needed.
+//
+// The cmd string may be multiple commands, separated by newlines. In that case
+// only one "step" is put on the undo stack representing all the commands.
+// Note that because of this, in "set A1 text ..." and "set A1 comment ..." text is
+// treated as encoded (newline => \n, \ => \b, : => \c).
+//
+// The commands are in the forms:
+//
+// set sheet attributename value (plus lastcol and lastrow)
+// set 22 attributename value
+// set B attributename value
+// set A1 attributename value1 value2... (see each attribute in code for details)
+// set A1:B5 attributename value1 value2...
+// erase/copy/cut/paste/fillright/filldown A1:B5 all/formulas/format
+// loadclipboard save-encoded-clipboard-data
+// clearclipboard
+// merge C3:F3
+// unmerge C3
+// insertcol/insertrow C5
+// deletecol/deleterow C5:E7
+// movepaste/moveinsert A1:B5 A8 (if insert, destination must be in same rows or columns or else paste done)
+// name define NAME definition
+// name desc NAME description
+// name delete NAME
+// recalc
+// redisplay
+//
+// If saveundo is true, then undo information is saved in sheet.changes.
+//
+
+SocialCalc.ExecuteSheetCommand = function(sheet, cmd, saveundo) {
+
+ var cmdstr, cmd1, rest, what, attrib, num, pos, pos2, errortext, undostart, val;
+ var cr1, cr2, col, row, cr, cell, newcell;
+ var fillright, rowstart, colstart, crbase, rowoffset, coloffset, basecell;
+ var clipsheet, cliprange, numcols, numrows, attribtable;
+ var colend, rowend, newcolstart, newrowstart, newcolend, newrowend, rownext, colnext, colthis, cellnext;
+ var lastrow, lastcol, rowbefore, colbefore, oldformula, oldcr;
+ var cols, dirs, lastsortcol, i, sortlist, sortcells, sortvalues, sorttypes;
+ var sortfunction, slen, valtype, originalrow, sortedcr;
+ var name, v1, v2;
+
+ var attribs = sheet.attribs;
+ var changes = sheet.changes;
+ var cellProperties = SocialCalc.CellProperties;
+ var scc = SocialCalc.Constants;
+
+ var ParseRange =
+ function() {
+ var prange = SocialCalc.ParseRange(what);
+ cr1 = prange.cr1;
+ cr2 = prange.cr2;
+ if (cr2.col > attribs.lastcol) attribs.lastcol = cr2.col;
+ if (cr2.row > attribs.lastrow) attribs.lastrow = cr2.row;
+ };
+
+ errortext = "";
+
+ cmdstr = cmd.RestOfStringNoMove();
+ if (saveundo) {
+ sheet.changes.AddDo(cmdstr);
+ }
+
+ cmd1 = cmd.NextToken();
+
+ switch (cmd1) {
+
+ case "set":
+ what = cmd.NextToken();
+ attrib = cmd.NextToken();
+ rest = cmd.RestOfString();
+ undostart = "set "+what+" "+attrib;
+
+ if (what=="sheet") {
+ sheet.renderneeded = true;
+ switch (attrib) {
+ case "defaultcolwidth":
+ if (saveundo) changes.AddUndo(undostart, attribs[attrib]);
+ attribs[attrib] = rest;
+ break;
+ case "defaultcolor":
+ case "defaultbgcolor":
+ if (saveundo) changes.AddUndo(undostart, sheet.GetStyleString("color", attribs[attrib]));
+ attribs[attrib] = sheet.GetStyleNum("color", rest);
+ break;
+ case "defaultlayout":
+ if (saveundo) changes.AddUndo(undostart, sheet.GetStyleString("layout", attribs[attrib]));
+ attribs[attrib] = sheet.GetStyleNum("layout", rest);
+ break;
+ case "defaultfont":
+ if (saveundo) changes.AddUndo(undostart, sheet.GetStyleString("font", attribs[attrib]));
+ if (rest=="* * *") rest = ""; // all default
+ attribs[attrib] = sheet.GetStyleNum("font", rest);
+ break;
+ case "defaulttextformat":
+ case "defaultnontextformat":
+ if (saveundo) changes.AddUndo(undostart, sheet.GetStyleString("cellformat", attribs[attrib]));
+ attribs[attrib] = sheet.GetStyleNum("cellformat", rest);
+ break;
+ case "defaulttextvalueformat":
+ case "defaultnontextvalueformat":
+ if (saveundo) changes.AddUndo(undostart, sheet.GetStyleString("valueformat", attribs[attrib]));
+ attribs[attrib] = sheet.GetStyleNum("valueformat", rest);
+ for (cr in sheet.cells) { // forget all cached display strings
+ delete sheet.cells[cr].displaystring;
+ }
+ break;
+ case "lastcol":
+ case "lastrow":
+ if (saveundo) changes.AddUndo(undostart, attribs[attrib]-0);
+ num = rest-0;
+ if (typeof num == "number") attribs[attrib] = num > 0 ? num : 1;
+ break;
+ case "recalc":
+ if (saveundo) changes.AddUndo(undostart, attribs[attrib]);
+ if (rest == "off") {
+ attribs.recalc = rest; // manual recalc, not auto
+ }
+ else { // all values other than "off" mean "on"
+ delete attribs.recalc;
+ }
+ break;
+ default:
+ errortext = scc.s_escUnknownSheetCmd+cmdstr;
+ break;
+ }
+ }
+
+ else if (/(^[A-Z])([A-Z])?(:[A-Z][A-Z]?){0,1}$/i.test(what)) { // col attributes
+ sheet.renderneeded = true;
+ what = what.toUpperCase();
+ pos = what.indexOf(":");
+ if (pos>=0) {
+ cr1 = SocialCalc.coordToCr(what.substring(0,pos)+"1");
+ cr2 = SocialCalc.coordToCr(what.substring(pos+1)+"1");
+ }
+ else {
+ cr1 = SocialCalc.coordToCr(what+"1");
+ cr2 = cr1;
+ }
+ for (col=cr1.col; col <= cr2.col; col++) {
+ if (attrib=="width") {
+ cr = SocialCalc.rcColname(col);
+ if (saveundo) changes.AddUndo("set "+cr+" width", sheet.colattribs.width[cr]);
+ if (rest.length > 0 ) {
+ sheet.colattribs.width[cr] = rest;
+ }
+ else {
+ delete sheet.colattribs.width[cr];
+ }
+ }
+ }
+ }
+
+ // !!!!! need row attribs !!!!
+
+ else if (/([a-z]){0,1}(\d+)/i.test(what)) { // cell attributes
+ ParseRange();
+ if (cr1.row!=cr2.row || cr1.col!=cr2.col || sheet.celldisplayneeded || sheet.renderneeded) { // not one cell
+ sheet.renderneeded = true;
+ sheet.celldisplayneeded = "";
+ }
+ else {
+ sheet.celldisplayneeded = SocialCalc.crToCoord(cr1.col, cr1.row);
+ }
+ for (row=cr1.row; row <= cr2.row; row++) {
+ for (col=cr1.col; col <= cr2.col; col++) {
+ cr = SocialCalc.crToCoord(col, row);
+ cell=sheet.GetAssuredCell(cr);
+ if (saveundo) changes.AddUndo("set "+cr+" all", sheet.CellToString(cell));
+ if (attrib=="value") { // set coord value type numeric-value
+ pos = rest.indexOf(" ");
+ cell.datavalue = rest.substring(pos+1)-0;
+ delete cell.errors;
+ cell.datatype = "v";
+ cell.valuetype = rest.substring(0,pos);
+ delete cell.displaystring;
+ delete cell.parseinfo;
+ attribs.needsrecalc = "yes";
+ }
+ else if (attrib=="text") { // set coord text type text-value
+ pos = rest.indexOf(" ");
+ cell.datavalue = SocialCalc.decodeFromSave(rest.substring(pos+1));
+ delete cell.errors;
+ cell.datatype = "t";
+ cell.valuetype = rest.substring(0,pos);
+ delete cell.displaystring;
+ delete cell.parseinfo;
+ attribs.needsrecalc = "yes";
+ }
+ else if (attrib=="formula") { // set coord formula formula-body-less-initial-=
+ cell.datavalue = 0; // until recalc
+ delete cell.errors;
+ cell.datatype = "f";
+ cell.valuetype = "e#N/A"; // until recalc
+ cell.formula = rest;
+ delete cell.displaystring;
+ delete cell.parseinfo;
+ attribs.needsrecalc = "yes";
+ }
+ else if (attrib=="constant") { // set coord constant type numeric-value source-text
+ pos = rest.indexOf(" ");
+ pos2 = rest.substring(pos+1).indexOf(" ");
+ cell.datavalue = rest.substring(pos+1,pos+1+pos2)-0;
+ cell.valuetype = rest.substring(0,pos);
+ if (cell.valuetype.charAt(0)=="e") { // error
+ cell.errors = cell.valuetype.substring(1);
+ }
+ else {
+ delete cell.errors;
+ }
+ cell.datatype = "c";
+ cell.formula = rest.substring(pos+pos2+2);
+ delete cell.displaystring;
+ delete cell.parseinfo;
+ attribs.needsrecalc = "yes";
+ }
+ else if (attrib=="empty") { // erase value
+ cell.datavalue = "";
+ delete cell.errors;
+ cell.datatype = null;
+ cell.formula = "";
+ cell.valuetype = "b";
+ delete cell.displaystring;
+ delete cell.parseinfo;
+ attribs.needsrecalc = "yes";
+ }
+ else if (attrib=="all") { // set coord all :this:val1:that:val2...
+ if (rest.length>0) {
+ cell = new SocialCalc.Cell(cr);
+ sheet.CellFromStringParts(cell, rest.split(":"), 1);
+ sheet.cells[cr] = cell;
+ }
+ else {
+ delete sheet.cells[cr];
+ }
+ attribs.needsrecalc = "yes";
+ }
+ else if (/^b[trbl]$/.test(attrib)) { // set coord bt 1px solid black
+ cell[attrib] = sheet.GetStyleNum("borderstyle", rest);
+ sheet.renderneeded = true; // affects more than just one cell
+ }
+ else if (attrib=="color" || attrib=="bgcolor") {
+ cell[attrib] = sheet.GetStyleNum("color", rest);
+ }
+ else if (attrib=="layout" || attrib=="cellformat") {
+ cell[attrib] = sheet.GetStyleNum(attrib, rest);
+ }
+ else if (attrib=="font") { // set coord font style weight size family
+ if (rest=="* * *") rest = "";
+ cell[attrib] = sheet.GetStyleNum("font", rest);
+ }
+ else if (attrib=="textvalueformat" || attrib=="nontextvalueformat") {
+ cell[attrib] = sheet.GetStyleNum("valueformat", rest);
+ delete cell.displaystring;
+ }
+ else if (attrib=="cssc") {
+ rest = rest.replace(/[^a-zA-Z0-9\-]/g, "");
+ cell.cssc = rest;
+ }
+ else if (attrib=="csss") {
+ rest = rest.replace(/\n/g, "");
+ cell.csss = rest;
+ }
+ else if (attrib=="mod") {
+ rest = rest.replace(/[^yY]/g, "").toLowerCase();
+ cell.mod = rest;
+ }
+ else if (attrib=="comment") {
+ cell.comment = SocialCalc.decodeFromSave(rest);
+ }
+ else {
+ errortext = scc.s_escUnknownSetCoordCmd+cmdstr;
+ }
+ }
+ }
+
+ }
+ break;
+
+ case "merge":
+ sheet.renderneeded = true;
+ what = cmd.NextToken();
+ rest = cmd.RestOfString();
+ ParseRange();
+ cell=sheet.GetAssuredCell(cr1.coord);
+ if (saveundo) changes.AddUndo("unmerge "+cr1.coord);
+
+ if (cr2.col > cr1.col) cell.colspan = cr2.col - cr1.col + 1;
+ else delete cell.colspan;
+ if (cr2.row > cr1.row) cell.rowspan = cr2.row - cr1.row + 1;
+ else delete cell.rowspan;
+
+ sheet.changedrendervalues = true;
+
+ break;
+
+ case "unmerge":
+ sheet.renderneeded = true;
+ what = cmd.NextToken();
+ rest = cmd.RestOfString();
+ ParseRange();
+ cell=sheet.GetAssuredCell(cr1.coord);
+ if (saveundo) changes.AddUndo("merge "+cr1.coord+":"+SocialCalc.crToCoord(cr1.col+(cell.colspan||1)-1, cr1.row+(cell.rowspan||1)-1));
+
+ delete cell.colspan;
+ delete cell.rowspan;
+
+ sheet.changedrendervalues = true;
+
+ break;
+
+ case "erase":
+ case "cut":
+ sheet.renderneeded = true;
+ sheet.changedrendervalues = true;
+ what = cmd.NextToken();
+ rest = cmd.RestOfString();
+ ParseRange();
+
+ if (cmd1=="cut") { // save copy of whole thing before erasing
+ if (saveundo) changes.AddUndo("loadclipboard", SocialCalc.encodeForSave(SocialCalc.Clipboard.clipboard));
+ SocialCalc.Clipboard.clipboard = SocialCalc.CreateSheetSave(sheet, what);
+ }
+
+ for (row = cr1.row; row <= cr2.row; row++) {
+ for (col = cr1.col; col <= cr2.col; col++) {
+ cr = SocialCalc.crToCoord(col, row);
+ cell=sheet.GetAssuredCell(cr);
+ if (saveundo) changes.AddUndo("set "+cr+" all", sheet.CellToString(cell));
+ if (rest=="all") {
+ delete sheet.cells[cr];
+ }
+ else if (rest == "formulas") {
+ cell.datavalue = "";
+ cell.datatype = null;
+ cell.formula = "";
+ cell.valuetype = "b";
+ delete cell.errors;
+ delete cell.displaystring;
+ delete cell.parseinfo;
+ if (cell.comment) { // comments are considered content for erasing
+ delete cell.comment;
+ }
+ }
+ else if (rest == "formats") {
+ newcell = new SocialCalc.Cell(cr); // create a new cell without attributes
+ newcell.datavalue = cell.datavalue; // copy existing values
+ newcell.datatype = cell.datatype;
+ newcell.formula = cell.formula;
+ newcell.valuetype = cell.valuetype;
+ if (cell.comment) {
+ newcell.comment = cell.comment;
+ }
+ sheet.cells[cr] = newcell; // replace
+ }
+ }
+ }
+ attribs.needsrecalc = "yes";
+ break;
+
+ case "fillright":
+ case "filldown":
+ sheet.renderneeded = true;
+ sheet.changedrendervalues = true;
+ what = cmd.NextToken();
+ rest = cmd.RestOfString();
+ ParseRange();
+ if (cmd1 == "fillright") {
+ fillright = true;
+ rowstart = cr1.row;
+ colstart = cr1.col + 1;
+ }
+ else {
+ fillright = false;
+ rowstart = cr1.row + 1;
+ colstart = cr1.col;
+ }
+ for (row = rowstart; row <= cr2.row; row++) {
+ for (col = colstart; col <= cr2.col; col++) {
+ cr = SocialCalc.crToCoord(col, row);
+ cell=sheet.GetAssuredCell(cr);
+ if (saveundo) changes.AddUndo("set "+cr+" all", sheet.CellToString(cell));
+ if (fillright) {
+ crbase = SocialCalc.crToCoord(cr1.col, row);
+ coloffset = col - colstart + 1;
+ rowoffset = 0;
+ }
+ else {
+ crbase = SocialCalc.crToCoord(col, cr1.row);
+ coloffset = 0;
+ rowoffset = row - rowstart + 1;
+ }
+ basecell = sheet.GetAssuredCell(crbase);
+ if (rest == "all" || rest == "formats") {
+ for (attrib in cellProperties) {
+ if (cellProperties[attrib] == 1) continue; // copy only format attributes
+ if (typeof basecell[attrib] === undefined || cellProperties[attrib] == 3) {
+ delete cell[attrib];
+ }
+ else {
+ cell[attrib] = basecell[attrib];
+ }
+ }
+ }
+ if (rest == "all" || rest == "formulas") {
+ cell.datavalue = basecell.datavalue;
+ cell.datatype = basecell.datatype;
+ cell.valuetype = basecell.valuetype;
+ if (cell.datatype == "f") { // offset relative coords, even in sheet references
+ cell.formula = SocialCalc.OffsetFormulaCoords(basecell.formula, coloffset, rowoffset);
+ }
+ else {
+ cell.formula = basecell.formula;
+ }
+ delete cell.parseinfo;
+ cell.errors = basecell.errors;
+ }
+ delete cell.displaystring;
+ }
+ }
+
+ attribs.needsrecalc = "yes";
+ break;
+
+ case "copy":
+ what = cmd.NextToken();
+ rest = cmd.RestOfString();
+ if (saveundo) changes.AddUndo("loadclipboard", SocialCalc.encodeForSave(SocialCalc.Clipboard.clipboard));
+ SocialCalc.Clipboard.clipboard = SocialCalc.CreateSheetSave(sheet, what);
+ break;
+
+ case "loadclipboard":
+ rest = cmd.RestOfString();
+ if (saveundo) changes.AddUndo("loadclipboard", SocialCalc.encodeForSave(SocialCalc.Clipboard.clipboard));
+ SocialCalc.Clipboard.clipboard = SocialCalc.decodeFromSave(rest);
+ break;
+
+ case "clearclipboard":
+ if (saveundo) changes.AddUndo("loadclipboard", SocialCalc.encodeForSave(SocialCalc.Clipboard.clipboard));
+ SocialCalc.Clipboard.clipboard = "";
+ break;
+
+ case "paste":
+ sheet.renderneeded = true;
+ sheet.changedrendervalues = true;
+ what = cmd.NextToken();
+ rest = cmd.RestOfString();
+ ParseRange();
+ if (!SocialCalc.Clipboard.clipboard) {
+ break;
+ }
+ clipsheet = new SocialCalc.Sheet(); // load clipboard contents as another sheet
+ clipsheet.ParseSheetSave(SocialCalc.Clipboard.clipboard);
+ cliprange = SocialCalc.ParseRange(clipsheet.copiedfrom);
+ coloffset = cr1.col - cliprange.cr1.col; // get sizes, etc.
+ rowoffset = cr1.row - cliprange.cr1.row;
+ numcols = cliprange.cr2.col - cliprange.cr1.col + 1;
+ numrows = cliprange.cr2.row - cliprange.cr1.row + 1;
+ if (cr1.col+numcols-1 > attribs.lastcol) attribs.lastcol = cr1.col+numcols-1;
+ if (cr1.row+numrows-1 > attribs.lastrow) attribs.lastrow = cr1.row+numrows-1;
+
+ for (row = cr1.row; row < cr1.row+numrows; row++) {
+ for (col = cr1.col; col < cr1.col+numcols; col++) {
+ cr = SocialCalc.crToCoord(col, row);
+ cell=sheet.GetAssuredCell(cr);
+ if (saveundo) changes.AddUndo("set "+cr+" all", sheet.CellToString(cell));
+ crbase = SocialCalc.crToCoord(col-coloffset, row-rowoffset);
+ basecell = clipsheet.GetAssuredCell(crbase);
+ if (rest == "all" || rest == "formats") {
+ for (attrib in cellProperties) {
+ if (cellProperties[attrib] == 1) continue; // copy only format attributes
+ if (typeof basecell[attrib] === undefined || cellProperties[attrib] == 3) {
+ delete cell[attrib];
+ }
+ else {
+ attribtable = SocialCalc.CellPropertiesTable[attrib];
+ if (attribtable && basecell[attrib]) { // table indexes to expand to strings since other sheet may have diff indexes
+ cell[attrib] = sheet.GetStyleNum(attribtable, clipsheet.GetStyleString(attribtable, basecell[attrib]));
+ }
+ else { // these are not table indexes
+ cell[attrib] = basecell[attrib];
+ }
+ }
+ }
+ }
+ if (rest == "all" || rest == "formulas") {
+ cell.datavalue = basecell.datavalue;
+ cell.datatype = basecell.datatype;
+ cell.valuetype = basecell.valuetype;
+ if (cell.datatype == "f") { // offset relative coords, even in sheet references
+ cell.formula = SocialCalc.OffsetFormulaCoords(basecell.formula, coloffset, rowoffset);
+ }
+ else {
+ cell.formula = basecell.formula;
+ }
+ delete cell.parseinfo;
+ cell.errors = basecell.errors;
+ if (basecell.comment) { // comments are pasted as part of content, though not filled, etc.
+ cell.comment = basecell.comment;
+ }
+ else if (cell.comment) {
+ delete cell.comment;
+ }
+ }
+ delete cell.displaystring;
+ }
+ }
+
+ attribs.needsrecalc = "yes";
+ break;
+
+ case "sort": // sort cr1:cr2 col1 up/down col2 up/down col3 up/down
+ sheet.renderneeded = true;
+ sheet.changedrendervalues = true;
+ what = cmd.NextToken();
+ ParseRange();
+ cols = []; // get columns and sort directions (or "")
+ dirs = [];
+ lastsortcol = 0;
+ for (i=0; i<=3; i++) {
+ cols[i] = cmd.NextToken();
+ dirs[i] = cmd.NextToken();
+ if (cols[i]) lastsortcol = i;
+ }
+
+ sortcells = {}; // a copy of the data which will replace the original, but in the new order
+ sortlist = []; // an array of 0, 1, ..., nrows-1 needed for sorting
+ sortvalues = []; // values to be sorted corresponding to sortlist
+ sorttypes = []; // basic types of the values
+
+ for (row = cr1.row; row <= cr2.row; row++) { // fill in the sort info
+ for (col = cr1.col; col <= cr2.col; col++) {
+ cr = SocialCalc.crToCoord(col, row);
+ cell=sheet.cells[cr];
+ if (cell) { // only copy non-empty cells
+ sortcells[cr] = sheet.CellToString(cell);
+ if (saveundo) changes.AddUndo("set "+cr+" all", sortcells[cr]);
+ }
+ else {
+ if (saveundo) changes.AddUndo("set "+cr+" all");
+ }
+ }
+ sortlist.push(sortlist.length);
+ sortvalues.push([]);
+ sorttypes.push([]);
+ slast = sorttypes.length-1;
+ for (i = 0; i <= lastsortcol; i++) {
+ cr = cols[i] + row; // get cr on this row in sort col
+ cell = sheet.GetAssuredCell(cr);
+ val = cell.datavalue;
+ valtype = cell.valuetype.charAt(0) || "b";
+ if (valtype == "t") val = val.toLowerCase();
+ sortvalues[slast].push(val);
+ sorttypes[slast].push(valtype);
+ }
+ }
+
+ sortfunction = function(a, b) { // a comparison function that can handle all the type variations
+ var i, a1, b1, ta, cresult;
+ for (i=0; i<=lastsortcol; i++) {
+ if (dirs[i] == "up") { // handle sort direction
+ a1 = a; b1 = b;
+ }
+ else {
+ a1 = b; b1 = a;
+ }
+ ta = sorttypes[a1][i];
+ tb = sorttypes[b1][i];
+ if (ta == "t") { // numbers < text < errors, blank always last no matter what dir
+ if (tb == "t") {
+ a1 = sortvalues[a1][i];
+ b1 = sortvalues[b1][i];
+ cresult = a1 > b1 ? 1 : (a1 < b1 ? -1 : 0);
+ }
+ else if (tb == "n") {
+ cresult = 1;
+ }
+ else if (tb == "b") {
+ cresult = dirs[i] == "up" ? -1 : 1;
+ }
+ else if (tb == "e") {
+ cresult = -1;
+ }
+ }
+ else if (ta == "n") {
+ if (tb == "t") {
+ cresult = -1;
+ }
+ else if (tb == "n") {
+ a1 = sortvalues[a1][i]-0; // force to numeric, just in case
+ b1 = sortvalues[b1][i]-0;
+ cresult = a1 > b1 ? 1 : (a1 < b1 ? -1 : 0);
+ }
+ else if (tb == "b") {
+ cresult = dirs[i] == "up" ? -1 : 1;
+ }
+ else if (tb == "e") {
+ cresult = -1;
+ }
+ }
+ else if (ta == "e") {
+ if (tb == "e") {
+ a1 = sortvalues[a1][i];
+ b1 = sortvalues[b1][i];
+ cresult = a1 > b1 ? 1 : (a1 < b1 ? -1 : 0);
+ }
+ else if (tb == "b") {
+ cresult = dirs[i] == "up" ? -1 : 1;
+ }
+ else {
+ cresult = 1;
+ }
+ }
+ else if (ta == "b") {
+ if (tb == "b") {
+ cresult = 0;
+ }
+ else {
+ cresult = dirs[i] == "up" ? 1 : -1;
+ }
+ }
+ if (cresult) { // return if tested not equal, otherwise do next column
+ return cresult;
+ }
+ }
+ cresult = a > b ? 1 : (a < b ? -1 : 0); // equal - return position in original to maintain it
+ return cresult;
+ }
+
+ sortlist.sort(sortfunction);
+
+ for (row = cr1.row; row <= cr2.row; row++) { // copy original rows into sorted positions
+ originalrow = sortlist[row-cr1.row]; // relative position where it was in original
+ for (col = cr1.col; col <= cr2.col; col++) {
+ cr = SocialCalc.crToCoord(col, row);
+ sortedcr = SocialCalc.crToCoord(col, originalrow+cr1.row); // original cell to be put in new place
+ if (sortcells[sortedcr]) {
+ cell = new SocialCalc.Cell(cr);
+ sheet.CellFromStringParts(cell, sortcells[sortedcr].split(":"), 1);
+ if (cell.datatype == "f") { // offset coord refs, even to ***relative*** coords in other sheets
+ cell.formula = SocialCalc.OffsetFormulaCoords(cell.formula, 0, (row-cr1.row)-originalrow);
+ }
+ sheet.cells[cr] = cell;
+ }
+ else {
+ delete sheet.cells[cr];
+ }
+ }
+ }
+
+ attribs.needsrecalc = "yes";
+ break;
+
+ case "insertcol":
+ case "insertrow":
+ sheet.renderneeded = true;
+ sheet.changedrendervalues = true;
+ what = cmd.NextToken();
+ rest = cmd.RestOfString();
+ ParseRange();
+
+ if (cmd1 == "insertcol") {
+ coloffset = 1;
+ colend = cr1.col;
+ rowoffset = 0;
+ rowend = 1;
+ newcolstart = cr1.col;
+ newcolend = cr1.col;
+ newrowstart = 1;
+ newrowend = attribs.lastrow;
+ if (saveundo) changes.AddUndo("deletecol "+cr1.coord);
+ }
+ else {
+ coloffset = 0;
+ colend = 1;
+ rowoffset = 1;
+ rowend = cr1.row;
+ newcolstart = 1;
+ newcolend = attribs.lastcol;
+ newrowstart = cr1.row;
+ newrowend = cr1.row;
+ if (saveundo) changes.AddUndo("deleterow "+cr1.coord);
+ }
+
+ for (row=attribs.lastrow; row >= rowend; row--) { // copy the cells forward
+ for (col=attribs.lastcol; col >= colend; col--) {
+ crbase = SocialCalc.crToCoord(col, row);
+ cr = SocialCalc.crToCoord(col+coloffset, row+rowoffset);
+ if (!sheet.cells[crbase]) { // copying empty cell
+ delete sheet.cells[cr]; // delete anything that may have been there
+ }
+ else { // overwrite existing cell with moved contents
+ sheet.cells[cr] = sheet.cells[crbase];
+ }
+ }
+ }
+
+ for (row=newrowstart; row <= newrowend; row++) { // fill the "new" empty cells
+ for (col=newcolstart; col <= newcolend; col++) {
+ cr = SocialCalc.crToCoord(col, row);
+ cell = new SocialCalc.Cell(cr);
+ sheet.cells[cr] = cell;
+ crbase = SocialCalc.crToCoord(col-coloffset, row-rowoffset); // copy attribs of the one before (0 gives you A or 1)
+ basecell = sheet.GetAssuredCell(crbase);
+ for (attrib in cellProperties) {
+ if (cellProperties[attrib] == 2) { // copy only format attributes
+ cell[attrib] = basecell[attrib];
+ }
+ }
+ }
+ }
+
+ for (cr in sheet.cells) { // update cell references to moved cells in calculated formulas
+ cell = sheet.cells[cr];
+ if (cell && cell.datatype == "f") {
+ cell.formula = SocialCalc.AdjustFormulaCoords(cell.formula, cr1.col, coloffset, cr1.row, rowoffset);
+ }
+ if (cell) {
+ delete cell.parseinfo;
+ }
+ }
+
+ for (name in sheet.names) { // update cell references to moved cells in names
+ if (sheet.names[name]) { // works with "A1", "A1:A20", and "=formula" forms
+ v1 = sheet.names[name].definition;
+ v2 = "";
+ if (v1.charAt(0) == "=") {
+ v2 = "=";
+ v1 = v1.substring(1);
+ }
+ sheet.names[name].definition = v2 +
+ SocialCalc.AdjustFormulaCoords(v1, cr1.col, coloffset, cr1.row, rowoffset);
+ }
+ }
+
+ for (row = attribs.lastrow; row >= rowend && cmd1 == "insertrow"; row--) { // copy the row attributes forward
+ rownext = row + rowoffset;
+ for (attrib in sheet.rowattribs) {
+ val = sheet.rowattribs[attrib][row];
+ if (sheet.rowattribs[attrib][rownext] != val) { // make assignment only if different
+ if (val) {
+ sheet.rowattribs[attrib][rownext] = val;
+ }
+ else {
+ delete sheet.rowattribs[attrib][rownext];
+ }
+ }
+ }
+ }
+
+ for (col = attribs.lastcol; col >= colend && cmd1 == "insertcol"; col--) { // copy the column attributes forward
+ colthis = SocialCalc.rcColname(col);
+ colnext = SocialCalc.rcColname(col + coloffset);
+ for (attrib in sheet.colattribs) {
+ val = sheet.colattribs[attrib][colthis];
+ if (sheet.colattribs[attrib][colnext] != val) { // make assignment only if different
+ if (val) {
+ sheet.colattribs[attrib][colnext] = val;
+ }
+ else {
+ delete sheet.colattribs[attrib][colnext];
+ }
+ }
+ }
+ }
+
+ attribs.lastcol += coloffset;
+ attribs.lastrow += rowoffset;
+ attribs.needsrecalc = "yes";
+ break;
+
+ case "deletecol":
+ case "deleterow":
+ sheet.renderneeded = true;
+ sheet.changedrendervalues = true;
+ what = cmd.NextToken();
+ rest = cmd.RestOfString();
+ lastcol = attribs.lastcol; // save old values since ParseRange sets...
+ lastrow = attribs.lastrow;
+ ParseRange();
+
+ if (cmd1 == "deletecol") {
+ coloffset = cr1.col - cr2.col - 1;
+ rowoffset = 0;
+ colstart = cr2.col + 1;
+ rowstart = 1;
+ }
+ else {
+ coloffset = 0;
+ rowoffset = cr1.row - cr2.row - 1;
+ colstart = 1;
+ rowstart = cr2.row + 1;
+ }
+
+ for (row=rowstart; row <= lastrow - rowoffset; row++) { // copy the cells backwards - extra so no dup of last set
+ for (col=colstart; col <= lastcol - coloffset; col++) {
+ cr = SocialCalc.crToCoord(col+coloffset, row+rowoffset);
+ if (saveundo && (row<rowstart-rowoffset || col<colstart -coloffset)) { // save cells that are overwritten as undo info
+ cell = sheet.cells[cr];
+ if (!cell) { // empty cell
+ changes.AddUndo("erase "+cr+" all");
+ }
+ else {
+ changes.AddUndo("set "+cr+" all", sheet.CellToString(cell));
+ }
+ }
+ crbase = SocialCalc.crToCoord(col, row);
+ cell = sheet.cells[crbase];
+ if (!cell) { // copying empty cell
+ delete sheet.cells[cr]; // delete anything that may have been there
+ }
+ else { // overwrite existing cell with moved contents
+ sheet.cells[cr] = cell;
+ }
+ }
+ }
+
+//!!! multiple deletes isn't setting #REF!; need to fix up #REF!'s on undo but only those!
+
+ for (cr in sheet.cells) { // update cell references to moved cells in calculated formulas
+ cell = sheet.cells[cr];
+ if (cell) {
+ if (cell.datatype == "f") {
+ oldformula = cell.formula;
+ cell.formula = SocialCalc.AdjustFormulaCoords(oldformula, cr1.col, coloffset, cr1.row, rowoffset);
+ if (cell.formula != oldformula) {
+ delete cell.parseinfo;
+ if (saveundo && cell.formula.indexOf("#REF!")!=-1) { // save old version only if removed coord
+ oldcr = SocialCalc.coordToCr(cr);
+ changes.AddUndo("set "+SocialCalc.rcColname(oldcr.col-coloffset)+(oldcr.row-rowoffset)+
+ " formula "+oldformula);
+ }
+ }
+ }
+ else {
+ delete cell.parseinfo;
+ }
+ }
+ }
+
+ for (name in sheet.names) { // update cell references to moved cells in names
+ if (sheet.names[name]) { // works with "A1", "A1:A20", and "=formula" forms
+ v1 = sheet.names[name].definition;
+ v2 = "";
+ if (v1.charAt(0) == "=") {
+ v2 = "=";
+ v1 = v1.substring(1);
+ }
+ sheet.names[name].definition = v2 +
+ SocialCalc.AdjustFormulaCoords(v1, cr1.col, coloffset, cr1.row, rowoffset);
+ }
+ }
+
+ for (row = rowstart; row <= lastrow - rowoffset && cmd1 == "deleterow"; row++) { // copy the row attributes backwards
+ rowbefore = row + rowoffset;
+ for (attrib in sheet.rowattribs) {
+ val = sheet.rowattribs[attrib][row];
+ if (sheet.rowattribs[attrib][rowbefore] != val) { // make assignment only if different
+ if (saveundo) changes.AddUndo("set "+rowbefore+" "+attrib, sheet.rowattribs[attrib][rowbefore]);
+ if (val) {
+ sheet.rowattribs[attrib][rowbefore] = val;
+ }
+ else {
+ delete sheet.rowattribs[attrib][rowbefore];
+ }
+ }
+ }
+ }
+
+ for (col = colstart; col <= lastcol - coloffset && cmd1 == "deletecol"; col++) { // copy the column attributes backwards
+ colthis = SocialCalc.rcColname(col);
+ colbefore = SocialCalc.rcColname(col + coloffset);
+ for (attrib in sheet.colattribs) {
+ val = sheet.colattribs[attrib][colthis];
+ if (sheet.colattribs[attrib][colbefore] != val) { // make assignment only if different
+ if (saveundo) changes.AddUndo("set "+colbefore+" "+attrib, sheet.colattribs[attrib][colbefore]);
+ if (val) {
+ sheet.colattribs[attrib][colbefore] = val;
+ }
+ else {
+ delete sheet.colattribs[attrib][colbefore];
+ }
+ }
+ }
+ }
+
+ if (saveundo) {
+ if (cmd1 == "deletecol") {
+ for (col=cr1.col; col<=cr2.col; col++) {
+ changes.AddUndo("insertcol "+SocialCalc.rcColname(col));
+ }
+ }
+ else {
+ for (row=cr1.row; row<=cr2.row; row++) {
+ changes.AddUndo("insertrow "+row);
+ }
+ }
+ }
+
+ if (cmd1 == "deletecol") {
+ if (cr1.col <= lastcol) { // shrink sheet unless deleted phantom cols off the end
+ if (cr2.col <= lastcol) {
+ attribs.lastcol += coloffset;
+ }
+ else {
+ attribs.lastcol = cr1.col - 1;
+ }
+ }
+ }
+ else {
+ if (cr1.row <= lastrow) { // shrink sheet unless deleted phantom rows off the end
+ if (cr2.row <= lastrow) {
+ attribs.lastrow += rowoffset;
+ }
+ else {
+ attribs.lastrow = cr1.row - 1;
+ }
+ }
+ }
+ attribs.needsrecalc = "yes";
+ break;
+
+
+ case "movepaste":
+ case "moveinsert":
+
+ var movingcells, destcr, inserthoriz, insertvert, pushamount, movedto;
+
+ sheet.renderneeded = true;
+ sheet.changedrendervalues = true;
+ what = cmd.NextToken();
+ rest = cmd.RestOfString();
+
+ ParseRange();
+
+ destcr = SocialCalc.coordToCr(rest);
+
+ coloffset = destcr.col - cr1.col;
+ rowoffset = destcr.row - cr1.row;
+ numcols = cr2.col - cr1.col + 1;
+ numrows = cr2.row - cr1.row + 1;
+
+ // get a copy of moving cells and erase from where they were
+
+ movingcells = {};
+
+ for (row = cr1.row; row <= cr2.row; row++) {
+ for (col = cr1.col; col <= cr2.col; col++) {
+ cr = SocialCalc.crToCoord(col, row);
+ cell=sheet.GetAssuredCell(cr);
+ if (saveundo) changes.AddUndo("set "+cr+" all", sheet.CellToString(cell));
+ if (sheet.cells[cr]) { // if had something
+ movingcells[cr] = sheet.cells[cr]; // save it
+ delete sheet.cells[cr]; // and delete from sheet
+ }
+ }
+ }
+
+ // if moveinsert, check destination OK, and calculate pushing parameters
+
+ if (cmd1 == "moveinsert") {
+ inserthoriz = false;
+ insertvert = false;
+ if (rowoffset==0 && (destcr.col < cr1.col || destcr.col > cr2.col)) {
+ if (destcr.col < cr1.col) { // moving left
+ pushamount = cr1.col - destcr.col;
+ inserthoriz = -1;
+ }
+ else {
+ destcr.col -= 1;
+ coloffset = destcr.col - cr2.col;
+ pushamount = destcr.col - cr2.col;
+ inserthoriz = 1;
+ }
+ }
+ else if (coloffset==0 && (destcr.row < cr1.row || destcr.row > cr2.row)) {
+ if (destcr.row < cr1.row) { // moving up
+ pushamount = cr1.row - destcr.row;
+ insertvert = -1;
+ }
+ else {
+ destcr.row -= 1;
+ rowoffset = destcr.row - cr2.row;
+ pushamount = destcr.row - cr2.row;
+ insertvert = 1;
+ }
+ }
+ else {
+ cmd1 = "movepaste"; // not allowed right now - ignore
+ }
+ }
+
+ // push any cells that need pushing
+
+ movedto = {}; // remember what was moved where
+
+ if (insertvert) {
+ for (row = 0; row < pushamount; row++) {
+ for (col = cr1.col; col <= cr2.col; col++) {
+ if (insertvert < 0) {
+ cr = SocialCalc.crToCoord(col, destcr.row+pushamount-row-1);
+ crbase = SocialCalc.crToCoord(col, cr2.row-row);
+ }
+ else {
+ cr = SocialCalc.crToCoord(col, destcr.row-pushamount+row+1);
+ crbase = SocialCalc.crToCoord(col, cr1.row+row);
+ }
+ cell=sheet.GetAssuredCell(cr);
+ if (saveundo) changes.AddUndo("set "+cr+" all", sheet.CellToString(cell));
+ if (sheet.cells[cr]) {
+ sheet.cells[crbase] = sheet.cells[cr];
+ }
+ else {
+ delete sheet.cells[crbase];
+ }
+ movedto[cr] = crbase; // old cr is now at crbase
+ }
+ }
+ }
+ if (inserthoriz) {
+ for (col = 0; col < pushamount; col++) {
+ for (row = cr1.row; row <= cr2.row; row++) {
+ if (inserthoriz < 0) {
+ cr = SocialCalc.crToCoord(destcr.col+pushamount-col-1, row);
+ crbase = SocialCalc.crToCoord(cr2.col-col, row);
+ }
+ else {
+ cr = SocialCalc.crToCoord(destcr.col-pushamount+col+1, row);
+ crbase = SocialCalc.crToCoord(cr1.col+col, row);
+ }
+ cell=sheet.GetAssuredCell(cr);
+ if (saveundo) changes.AddUndo("set "+cr+" all", sheet.CellToString(cell));
+ if (sheet.cells[cr]) {
+ sheet.cells[crbase] = sheet.cells[cr];
+ }
+ else {
+ delete sheet.cells[crbase];
+ }
+ movedto[cr] = crbase; // old cr is now at crbase
+ }
+ }
+ }
+
+ // paste moved cells into new place
+
+ if (destcr.col+numcols-1 > attribs.lastcol) attribs.lastcol = destcr.col+numcols-1;
+ if (destcr.row+numrows-1 > attribs.lastrow) attribs.lastrow = destcr.row+numrows-1;
+
+ for (row = cr1.row; row < cr1.row+numrows; row++) {
+ for (col = cr1.col; col < cr1.col+numcols; col++) {
+ cr = SocialCalc.crToCoord(col+coloffset, row+rowoffset);
+ cell=sheet.GetAssuredCell(cr);
+ if (saveundo) changes.AddUndo("set "+cr+" all", sheet.CellToString(cell));
+ delete sheet.cells[cr]; // delete what used to be there at destination
+
+ crbase = SocialCalc.crToCoord(col, row); // get old cell to move
+ if (movingcells[crbase]) { // if has something
+ sheet.cells[cr] = movingcells[crbase]; // copy it in
+ }
+ movedto[crbase] = cr; // old crbase (moved cell) is now at cr (destination)
+ }
+ }
+
+ // do fixups
+
+ for (cr in sheet.cells) { // update cell references to moved cells in calculated formulas
+ cell = sheet.cells[cr];
+ if (cell) {
+ if (cell.datatype == "f") {
+ oldformula = cell.formula;
+ cell.formula = SocialCalc.ReplaceFormulaCoords(oldformula, movedto);
+ if (cell.formula != oldformula) {
+ delete cell.parseinfo;
+ if (saveundo && !movedto[cr]) { // moved cells are already saved for undo
+ changes.AddUndo("set "+cr+" formula "+oldformula);
+ }
+ }
+ }
+ else {
+ delete cell.parseinfo;
+ }
+ }
+ }
+
+ for (name in sheet.names) { // update cell references to moved cells in names
+ if (sheet.names[name]) { // works with "A1", "A1:A20", and "=formula" forms
+ v1 = sheet.names[name].definition;
+ oldformula = v1;
+ v2 = "";
+ if (v1.charAt(0) == "=") {
+ v2 = "=";
+ v1 = v1.substring(1);
+ }
+ sheet.names[name].definition = v2 +
+ SocialCalc.ReplaceFormulaCoords(v1, movedto);
+ if (saveundo && sheet.names[name].definition != oldformula) { // save changes
+ changes.AddUndo("name define "+name+" "+oldformula);
+ }
+ }
+ }
+
+ attribs.needsrecalc = "yes";
+ break;
+
+ case "name":
+ what = cmd.NextToken();
+ name = cmd.NextToken();
+ rest = cmd.RestOfString();
+
+ name = name.toUpperCase().replace(/[^A-Z0-9_\.]/g, "");
+ if (name == "") break; // must have something
+
+ if (what == "define") {
+ if (rest == "") break; // must have something
+ if (sheet.names[name]) { // already exists
+ if (saveundo) changes.AddUndo("name define "+name+" "+sheet.names[name].definition);
+ sheet.names[name].definition = rest;
+ }
+ else { // new
+ if (saveundo) changes.AddUndo("name delete "+name);
+ sheet.names[name] = {definition: rest, desc: ""};
+ }
+ }
+ else if (what == "desc") {
+ if (sheet.names[name]) { // must already exist
+ if (saveundo) changes.AddUndo("name desc "+name+" "+sheet.names[name].desc);
+ sheet.names[name].desc = rest;
+ }
+ }
+ else if (what == "delete") {
+ if (saveundo) {
+ if (sheet.names[name].desc) changes.AddUndo("name desc "+name+" "+sheet.names[name].desc);
+ changes.AddUndo("name define "+name+" "+sheet.names[name].definition);
+ }
+ delete sheet.names[name];
+ }
+ attribs.needsrecalc = "yes";
+
+ break;
+
+ case "recalc":
+ attribs.needsrecalc = "yes"; // request recalc
+ sheet.recalconce = true; // even if turned off
+ break;
+
+ case "redisplay":
+ sheet.renderneeded = true;
+ break;
+
+ default:
+ errortext = scc.s_escUnknownCmd+cmdstr;
+ break;
+ }
+
+/* For Debugging:
+var ustack="";
+for (var i=0;i<sheet.changes.stack.length;i++) {
+ ustack+=(i-0)+":"+sheet.changes.stack[i].command[0]+" of "+sheet.changes.stack[i].command.length+"/"+sheet.changes.stack[i].undo[0]+" of "+sheet.changes.stack[i].undo.length+",";
+ }
+alert(cmdstr+"|"+sheet.changes.stack.length+"--"+ustack);
+*/
+
+ return errortext;
+
+ }
+
+SocialCalc.SheetUndo = function(sheet) {
+
+ var i;
+ var tos = sheet.changes.TOS();
+ var lastone = tos ? tos.undo.length-1 : -1;
+ var cmdstr = "";
+
+ for (i=lastone; i>=0; i--) { // do them backwards
+ if (cmdstr) cmdstr += "\n"; // concatenate with separate lines
+ cmdstr += tos.undo[i];
+ }
+ sheet.changes.Undo();
+ sheet.ScheduleSheetCommands(cmdstr, false); // do undo operations
+
+ }
+
+SocialCalc.SheetRedo = function(sheet) {
+
+ var tos, i;
+ var didredo = sheet.changes.Redo();
+ if (!didredo) {
+ sheet.ScheduleSheetCommands("", false); // schedule doing nothing
+ return;
+ }
+ tos = sheet.changes.TOS();
+ var cmdstr = "";
+
+ for (i=0; tos && i<tos.command.length; i++) {
+ if (cmdstr) cmdstr += "\n"; // concatenate with separate lines
+ cmdstr += tos.command[i];
+ }
+ sheet.ScheduleSheetCommands(cmdstr, false); // do undo operations
+
+ }
+
+SocialCalc.CreateAuditString = function(sheet) {
+
+ var i, j;
+ var result = "";
+ var stack = sheet.changes.stack;
+ var tos = sheet.changes.tos;
+ for (i=0; i<=tos; i++) {
+ for (j=0; j<stack[i].command.length; j++) {
+ result += stack[i].command[j] + "\n";
+ }
+ }
+
+ return result;
+
+ }
+
+SocialCalc.GetStyleNum = function(sheet, atype, style) {
+
+ var num;
+
+ if (style.length==0) return 0; // null means use zero, which means default or global default
+
+ num = sheet[atype+"hash"][style];
+ if (!num) {
+ if (sheet[atype+"s"].length<1) sheet[atype+"s"].push("");
+ num = sheet[atype+"s"].push(style) - 1;
+ sheet[atype+"hash"][style] = num;
+ sheet.changedrendervalues = true;
+ }
+ return num;
+
+ }
+
+SocialCalc.GetStyleString = function(sheet, atype, num) {
+
+ if (!num) return null; // zero, null, and undefined return null
+
+ return sheet[atype+"s"][num];
+
+ }
+
+//
+// updatedformula = SocialCalc.OffsetFormulaCoords(formula, coloffset, rowoffset)
+//
+// Change relative cell references by offsets (even those to other worksheets so fill, paste, sort work as expected).
+// If not what you want, use absolute references.
+//
+
+SocialCalc.OffsetFormulaCoords = function(formula, coloffset, rowoffset) {
+
+ var parseinfo, ttext, ttype, i, cr, newcr;
+ var updatedformula = "";
+ var scf = SocialCalc.Formula;
+ if (!scf) {
+ return "Need SocialCalc.Formula";
+ }
+ var tokentype = scf.TokenType;
+ var token_op = tokentype.op;
+ var token_string = tokentype.string;
+ var token_coord = tokentype.coord;
+ var tokenOpExpansion = scf.TokenOpExpansion;
+
+ parseinfo = scf.ParseFormulaIntoTokens(formula);
+
+ for (i=0; i<parseinfo.length; i++) {
+ ttype = parseinfo[i].type;
+ ttext = parseinfo[i].text;
+ if (ttype == token_coord) {
+ newcr = "";
+ cr = SocialCalc.coordToCr(ttext);
+ if (ttext.charAt(0)!="$") { // add col offset unless absolute column
+ cr.col += coloffset;
+ }
+ else {
+ newcr += "$";
+ }
+ newcr += SocialCalc.rcColname(cr.col);
+ if (ttext.indexOf("$", 1)==-1) { // add row offset unless absolute row
+ cr.row += rowoffset;
+ }
+ else {
+ newcr += "$";
+ }
+ newcr += cr.row;
+ if (cr.row < 1 || cr.col < 1) {
+ newcr = "#REF!";
+ }
+ updatedformula += newcr;
+ }
+ else if (ttype == token_string) {
+ if (ttext.indexOf('"') >= 0) { // quotes to double
+ updatedformula += '"' + ttext.replace(/"/, '""') + '"';
+ }
+ else updatedformula += '"' + ttext + '"';
+ }
+ else if (ttype == token_op) {
+ updatedformula += tokenOpExpansion[ttext] || ttext; // make sure short tokens (e.g., "G") go back full (">=")
+ }
+ else { // leave everything else alone
+ updatedformula += ttext;
+ }
+ }
+
+ return updatedformula;
+
+ }
+
+//
+// updatedformula = SocialCalc.AdjustFormulaCoords(formula, col, coloffset, row, rowoffset)
+//
+// Change all cell references to cells starting with col/row by offsets
+//
+
+SocialCalc.AdjustFormulaCoords = function(formula, col, coloffset, row, rowoffset) {
+
+ var ttype, ttext, i, newcr;
+ var updatedformula = "";
+ var sheetref = false;
+ var scf = SocialCalc.Formula;
+ if (!scf) {
+ return "Need SocialCalc.Formula";
+ }
+ var tokentype = scf.TokenType;
+ var token_op = tokentype.op;
+ var token_string = tokentype.string;
+ var token_coord = tokentype.coord;
+ var tokenOpExpansion = scf.TokenOpExpansion;
+
+ parseinfo = SocialCalc.Formula.ParseFormulaIntoTokens(formula);
+
+ for (i=0; i<parseinfo.length; i++) {
+ ttype = parseinfo[i].type;
+ ttext = parseinfo[i].text;
+ if (ttype == token_op) { // references with sheet specifier are not offset
+ if (ttext == "!") {
+ sheetref = true; // found a sheet reference
+ }
+ else if (ttext != ":") { // for everything but a range, reset
+ sheetref = false;
+ }
+ ttext = tokenOpExpansion[ttext] || ttext; // make sure short tokens (e.g., "G") go back full (">=")
+ }
+ if (ttype == token_coord) {
+ cr = SocialCalc.coordToCr(ttext);
+ if ((coloffset < 0 && cr.col >= col && cr.col < col-coloffset) ||
+ (rowoffset < 0 && cr.row >= row && cr.row < row-rowoffset)) { // refs to deleted cells become invalid
+ if (!sheetref) {
+ cr.col = 0;
+ cr.row = 0;
+ }
+ }
+ if (!sheetref) {
+ if (cr.col >= col) {
+ cr.col += coloffset;
+ }
+ if (cr.row >= row) {
+ cr.row += rowoffset;
+ }
+ }
+ if (ttext.charAt(0)=="$") {
+ newcr = "$"+SocialCalc.rcColname(cr.col);
+ }
+ else {
+ newcr = SocialCalc.rcColname(cr.col);
+ }
+ if (ttext.indexOf("$", 1)!=-1) {
+ newcr += "$" + cr.row;
+ }
+ else {
+ newcr += cr.row;
+ }
+ if (cr.row < 1 || cr.col < 1) {
+ newcr = "#REF!";
+ }
+ ttext = newcr;
+ }
+ else if (ttype == token_string) {
+ if (ttext.indexOf('"') >= 0) { // quotes to double
+ ttext = '"' + ttext.replace(/"/, '""') + '"';
+ }
+ else ttext = '"' + ttext + '"';
+ }
+ updatedformula += ttext;
+ }
+
+ return updatedformula;
+
+ }
+
+//
+// updatedformula = SocialCalc.ReplaceFormulaCoords(formula, movedto)
+//
+// Change all cell references to cells that are keys in moveto to be to moveto[coord].
+// Don't change references to other sheets.
+// Handle range extents specially.
+//
+
+SocialCalc.ReplaceFormulaCoords = function(formula, movedto) {
+
+ var ttype, ttext, i, newcr, coord;
+ var updatedformula = "";
+ var sheetref = false;
+ var scf = SocialCalc.Formula;
+ if (!scf) {
+ return "Need SocialCalc.Formula";
+ }
+ var tokentype = scf.TokenType;
+ var token_op = tokentype.op;
+ var token_string = tokentype.string;
+ var token_coord = tokentype.coord;
+ var tokenOpExpansion = scf.TokenOpExpansion;
+
+ parseinfo = SocialCalc.Formula.ParseFormulaIntoTokens(formula);
+
+ for (i=0; i<parseinfo.length; i++) {
+ ttype = parseinfo[i].type;
+ ttext = parseinfo[i].text;
+ if (ttype == token_op) { // references with sheet specifier are not change
+ if (ttext == "!") {
+ sheetref = true; // found a sheet reference
+ }
+ else if (ttext != ":") { // for everything but a range, reset
+ sheetref = false;
+ }
+
+//!!!! HANDLE RANGE EXTENT MOVES
+
+ ttext = tokenOpExpansion[ttext] || ttext; // make sure short tokens (e.g., "G") go back full (">=")
+ }
+ if (ttype == token_coord) {
+ cr = SocialCalc.coordToCr(ttext); // get parts
+ coord = SocialCalc.crToCoord(cr.col, cr.row); // get "clean" reference
+ if (movedto[coord] && !sheetref) { // this is a reference to a moved cell
+ cr = SocialCalc.coordToCr(movedto[coord]); // get new row and col
+ if (ttext.charAt(0)=="$") { // copy absolute ref marks if present
+ newcr = "$"+SocialCalc.rcColname(cr.col);
+ }
+ else {
+ newcr = SocialCalc.rcColname(cr.col);
+ }
+ if (ttext.indexOf("$", 1)!=-1) {
+ newcr += "$" + cr.row;
+ }
+ else {
+ newcr += cr.row;
+ }
+ ttext = newcr;
+ }
+ }
+ else if (ttype == token_string) {
+ if (ttext.indexOf('"') >= 0) { // quotes to double
+ ttext = '"' + ttext.replace(/"/, '""') + '"';
+ }
+ else ttext = '"' + ttext + '"';
+ }
+ updatedformula += ttext;
+ }
+
+ return updatedformula;
+
+ }
+
+
+// ************************
+//
+// Recalc Loop Code
+//
+// ************************
+
+//
+// How recalc works:
+//
+// !!!!!!!!!!!!!!
+//
+
+// SocialCalc.RecalcInfo - object with global recalc info
+
+SocialCalc.RecalcInfo = {
+
+ sheet: null, // which sheet is being recalced
+
+ currentState: 0, // current state
+ state: {start_calc: 1, order: 2, calc: 3, start_wait: 4, done_wait: 5}, // allowed state values
+
+ recalctimer: null, // value to cancel timer
+ maxtimeslice: 100, // maximum milliseconds per slice of recalc time before a wait
+ timeslicedelay: 1, // milliseconds to wait between recalc time slices
+ starttime: 0, // when recalc started
+
+ // LoadSheet: a function that returns true if started a load or false if not.
+ //
+
+ LoadSheet: function(sheetname) {return false;} // default returns not found
+
+ }
+
+// SocialCalc.RecalcData - object with recalc info while determining recalc order and afterward
+
+SocialCalc.RecalcData = function() { // initialize a RecalcData object
+
+ this.inrecalc = true; // if true, doing a recalc
+ this.celllist = []; // list with all potential cells to calculate
+ this.celllistitem = 0; // cell to check next when ordering
+ this.calclist = null; // object which is the chained list of cells to calculate
+ // each in the form of "coord: nextcoord"
+ // e.g., if B8 is calculated right after A8, then calclist.A8=="B8"
+ // if null, need to create the list
+ this.calclistlength = 0; // number of items in calclist
+
+ this.firstcalc = null; // start of the calc list - a string or null
+ this.lastcalc = null; // last one on chain (used to add more to the end)
+
+ this.nextcalc = null; // used to keep track during background recalc to make it restartable
+ this.count = 0; // number calculated
+
+ // checkinfo is used when determining calc order:
+
+ this.checkinfo = {}; // attributes are coords; if no attrib for a coord, it wasn't checked or doesn't need it
+ // values are RecalcCheckInfo objects while checking or TRUE when complete
+
+ }
+
+// SocialCalc.RecalcCheckInfo - object that stores checking info while determining recalc order
+
+SocialCalc.RecalcCheckInfo = function() { // initialize a RecalcCheckInfo object
+
+ this.oldcoord = null; // chain back up of cells referring to cells
+ this.parsepos = 0; // which token we are up to
+
+ // range info
+
+ this.inrange = false; // if true, in the process of checking a range of coords
+ this.inrangestart = false; // if true, have not yet filled in range loop values
+ this.cr1 = null; // range first coord as a cr object
+ this.cr2 = null; // range second coord as a cr object
+ this.c1 = null; // range extents
+ this.c2 = null;
+ this.r1 = null;
+ this.r2 = null;
+ this.c = null; // looping values
+ this.r = null;
+
+ }
+
+// Recalc the entire sheet
+
+SocialCalc.RecalcSheet = function(sheet) {
+
+ var coord, err, recalcdata;
+ var scri = SocialCalc.RecalcInfo;
+
+ delete sheet.attribs.circularreferencecell; // reset recalc-wide things
+ SocialCalc.Formula.FreshnessInfoReset();
+
+ SocialCalc.RecalcClearTimeout();
+
+ scri.sheet = sheet; // set values needed by background recalc
+ scri.currentState = scri.state.start_calc;
+
+ scri.starttime = new Date();
+
+ if (sheet.statuscallback) {
+ sheet.statuscallback(scri, "calcstart", null, sheet.statuscallbackparams);
+ }
+
+ SocialCalc.RecalcSetTimeout();
+
+ }
+
+//
+// SocialCalc.RecalcSetTimeout - set a timer for next recalc step
+//
+
+SocialCalc.RecalcSetTimeout = function() {
+
+ var scri = SocialCalc.RecalcInfo;
+
+ scri.recalctimer = window.setTimeout(SocialCalc.RecalcTimerRoutine, scri.timeslicedelay);
+
+ }
+
+//
+// SocialCalc.RecalcClearTimeout - cancel any timeouts
+//
+
+SocialCalc.RecalcClearTimeout = function() {
+
+ var scri = SocialCalc.RecalcInfo;
+
+ if (scri.recalctimer) {
+ window.clearTimeout(scri.recalctimer);
+ scri.recalctimer = null;
+ }
+
+ }
+
+
+//
+// SocialCalc.RecalcLoadedSheet(sheetname, str, recalcneeded)
+//
+// Called when a sheet finishes loading with name, string, and t/f whether it should be recalced.
+// If loaded sheet has sheet.attribs.recalc=="off", then no recalc done.
+// If sheetname is null, then the sheetname waiting for will be used.
+//
+
+SocialCalc.RecalcLoadedSheet = function(sheetname, str, recalcneeded) {
+
+ var sheet;
+ var scri = SocialCalc.RecalcInfo;
+ var scf = SocialCalc.Formula;
+
+ sheet = SocialCalc.Formula.AddSheetToCache(sheetname || scf.SheetCache.waitingForLoading, str);
+
+ if (recalcneeded && sheet && sheet.attribs.recalc!="off") { // if recalcneeded, and not manual sheet, chain in this new sheet to recalc loop
+ sheet.previousrecalcsheet = scri.sheet;
+ scri.sheet = sheet;
+ scri.currentState = scri.state.start_calc;
+ }
+ scf.SheetCache.waitingForLoading = null;
+
+ SocialCalc.RecalcSetTimeout();
+
+ }
+
+
+//
+// SocialCalc.RecalcTimerRoutine - handles the actual order determination and cell-by-cell recalculation in the background
+//
+
+SocialCalc.RecalcTimerRoutine = function() {
+
+ var eresult, cell, coord, err, status;
+ var starttime = new Date();
+ var count = 0;
+ var scf = SocialCalc.Formula;
+ if (!scf) {
+ return "Need SocialCalc.Formula";
+ }
+ var scri = SocialCalc.RecalcInfo;
+ var sheet = scri.sheet;
+ if (!sheet) {
+ return;
+ }
+ var recalcdata = sheet.recalcdata;
+
+ var do_statuscallback = function(status, arg) { // routine to do callback if required
+ if (sheet.statuscallback) {
+ sheet.statuscallback(recalcdata, status, arg, sheet.statuscallbackparams);
+ }
+ }
+
+ SocialCalc.RecalcClearTimeout();
+
+ if (scri.currentState == scri.state.start_calc) {
+
+ recalcdata = new SocialCalc.RecalcData();
+ sheet.recalcdata = recalcdata;
+
+ for (coord in sheet.cells) { // get list of cells to check for order
+ if (!coord) continue;
+ recalcdata.celllist.push(coord);
+ }
+
+ recalcdata.calclist = {}; // start with empty list
+ scri.currentState = scri.state.order; // drop through to determining recalc order
+ }
+
+ if (scri.currentState == scri.state.order) {
+ while (recalcdata.celllistitem < recalcdata.celllist.length) { // check all the cells to see if they should be on the list
+ coord = recalcdata.celllist[recalcdata.celllistitem++];
+ err = SocialCalc.RecalcCheckCell(sheet, coord);
+ if (((new Date()) - starttime) >= scri.maxtimeslice) { // if taking too long, give up CPU for a while
+ do_statuscallback("calcorder", {coord: coord, total: recalcdata.celllist.length, count: recalcdata.celllistitem});
+ SocialCalc.RecalcSetTimeout();
+ return;
+ }
+ }
+
+ do_statuscallback("calccheckdone", recalcdata.calclistlength);
+
+ recalcdata.nextcalc = recalcdata.firstcalc; // start at the beginning of the recalc chain
+ scri.currentState = scri.state.calc; // loop through cells on next timer call
+ SocialCalc.RecalcSetTimeout();
+ return;
+ }
+
+ if (scri.currentState == scri.state.start_wait) { // starting to wait for something
+ scri.currentState = scri.state.done_wait; // finished on next timer call
+ if (scri.LoadSheet) {
+ status = scri.LoadSheet(scf.SheetCache.waitingForLoading);
+ if (status) { // started a load operation
+ return;
+ }
+ }
+ SocialCalc.RecalcLoadedSheet(null, "", false);
+ return;
+ }
+
+ if (scri.currentState == scri.state.done_wait) {
+ scri.currentState = scri.state.calc; // loop through cells on next timer call
+ SocialCalc.RecalcSetTimeout();
+ return;
+ }
+
+ // otherwise should be scri.state.calc
+
+ if (scri.currentState != scri.state.calc) {
+ alert("Recalc state error: "+scri.currentState+". Error in SocialCalc code.");
+ }
+
+ coord = sheet.recalcdata.nextcalc;
+ while (coord) {
+ cell = sheet.cells[coord];
+ eresult = scf.evaluate_parsed_formula(cell.parseinfo, sheet, false);
+ if (scf.SheetCache.waitingForLoading) { // wait until restarted
+ recalcdata.nextcalc = coord; // start with this cell again
+ recalcdata.count += count;
+ do_statuscallback("calcloading", {sheetname: scf.SheetCache.waitingForLoading});
+ scri.currentState = scri.state.start_wait; // start load on next timer call
+ SocialCalc.RecalcSetTimeout();
+ return;
+ }
+
+ if (scf.RemoteFunctionInfo.waitingForServer) { // wait until restarted
+ recalcdata.nextcalc = coord; // start with this cell again
+ recalcdata.count += count;
+ do_statuscallback("calcserverfunc",
+ {funcname: scf.RemoteFunctionInfo.waitingForServer, coord: coord, total: recalcdata.calclistlength, count: recalcdata.count});
+ scri.currentState = scri.state.done_wait; // start load on next timer call
+ return; // return and wait for next recalc timer event
+ }
+
+ if (cell.datavalue != eresult.value ||
+ cell.valuetype != eresult.type) { // only update if changed from last time
+ cell.datavalue = eresult.value;
+ cell.valuetype = eresult.type;
+ delete cell.displaystring;
+ sheet.recalcchangedavalue = true; // remember something changed in case other code wants to know
+ }
+ if (eresult.error) {
+ cell.errors = eresult.error;
+ }
+ count++;
+ coord = sheet.recalcdata.calclist[coord];
+
+ if (((new Date()) - starttime) >= scri.maxtimeslice) { // if taking too long, give up CPU for a while
+ recalcdata.nextcalc = coord; // start with next cell on chain
+ recalcdata.count += count;
+ do_statuscallback("calcstep", {coord: coord, total: recalcdata.calclistlength, count: recalcdata.count});
+ SocialCalc.RecalcSetTimeout();
+ return;
+ }
+ }
+
+ recalcdata.inrecalc = false;
+
+ delete sheet.recalcdata; // save memory and clear out for name lookup formula evaluation
+
+ delete sheet.attribs.needsrecalc; // remember recalc done
+
+ scri.sheet = sheet.previousrecalcsheet || null; // chain back if doing recalc of loaded sheets
+ if (scri.sheet) {
+ scri.currentState = scri.state.calc; // start where we left off
+ SocialCalc.RecalcSetTimeout();
+ return;
+ }
+
+ scf.FreshnessInfo.recalc_completed = true; // say freshness info is complete
+
+ do_statuscallback("calcfinished", (new Date()) - scri.starttime);
+
+ }
+
+
+//
+// circref = SocialCalc.RecalcCheckCell(sheet, coord)
+//
+// Checks cell to put on calclist, looking at parsed tokens.
+// Also checks cells this cell is dependent upon
+// if it contains a formula with cell references.
+// If circular reference, returns non-null.
+//
+
+SocialCalc.RecalcCheckCell = function(sheet, startcoord) {
+
+ var parseinfo, ttext, ttype, i, rangecoord, circref, value, pos, pos2, cell, coordvals;
+ var scf = SocialCalc.Formula;
+ if (!scf) {
+ return "Need SocialCalc.Formula";
+ }
+ var tokentype = scf.TokenType;
+ var token_op = tokentype.op;
+ var token_name = tokentype.name;
+ var token_coord = tokentype.coord;
+
+ var recalcdata = sheet.recalcdata;
+ var checkinfo = recalcdata.checkinfo;
+
+ var sheetref = false; // if true, a sheet reference is in effect, so don't check that
+ var oldcoord = null; // coord of formula that referred to this one when checking down the tree
+ var coord = startcoord; // the coord of the cell we are checking
+
+ // Start with requested cell, and then continue down or up the dependency tree
+ // oldcoord (and checkinfo[coord].oldcoord) maintains the reference stack during the tree walk
+ // checkinfo[coord] maintains the stack of checking looping values, e.g., token number being checked
+
+mainloop:
+ while (coord) {
+ cell = sheet.cells[coord];
+ coordvals = checkinfo[coord];
+
+ if (!cell || cell.datatype != "f" || // Don't calculate if not a formula
+ (coordvals && typeof coordvals != "object")) { // Don't calc if already calculated
+ coord = oldcoord; // go back up dependency tree to coord that referred to us
+ if (checkinfo[coord]) oldcoord = checkinfo[coord].oldcoord;
+ continue;
+ }
+
+ if (!coordvals) { // do we have checking information about this cell?
+ coordvals = new SocialCalc.RecalcCheckInfo(); // no - make a place to hold it
+ checkinfo[coord] = coordvals;
+ }
+
+ if (cell.errors) { // delete errors from previous recalcs
+ delete cell.errors;
+ }
+
+ if (!cell.parseinfo) { // cache parsed formula
+ cell.parseinfo = scf.ParseFormulaIntoTokens(cell.formula);
+ }
+ parseinfo = cell.parseinfo;
+
+ for (i=coordvals.parsepos; i<parseinfo.length; i++) { // go through each token in formula
+
+ if (coordvals.inrange) { // processing a range of coords
+ if (coordvals.inrangestart) { // first time - fill in other values
+ if (coordvals.cr1.col > coordvals.cr2.col) { coordvals.c1 = coordvals.cr2.col; coordvals.c2 = coordvals.cr1.col; }
+ else { coordvals.c1 = coordvals.cr1.col; coordvals.c2 = coordvals.cr2.col; }
+ coordvals.c = coordvals.c1 - 1; // start one before
+
+ if (coordvals.cr1.row > coordvals.cr2.row) { coordvals.r1 = coordvals.cr2.row; coordvals.r2 = coordvals.cr1.row; }
+ else { coordvals.r1 = coordvals.cr1.row; coordvals.r2 = coordvals.cr2.row; }
+ coordvals.r = coordvals.r1; // start on this row
+ coordvals.inrangestart = false;
+ }
+ else { // not first time
+ }
+ coordvals.c += 1; // increment column
+ if (coordvals.c > coordvals.c2) { // finished the columns of this row
+ coordvals.r += 1; // increment row
+ if (coordvals.r > coordvals.r2) { // finished checking the entire range
+ coordvals.inrange = false;
+ continue;
+ }
+ coordvals.c = coordvals.c1; // start at the beginning of next row
+ }
+ rangecoord = SocialCalc.crToCoord(coordvals.c, coordvals.r);
+
+ // now check that one
+
+ coordvals.parsepos = i; // remember our position
+ coordvals.oldcoord = oldcoord; // remember back up chain
+ oldcoord = coord; // come back to us
+ coord = rangecoord;
+ if (checkinfo[coord] && typeof checkinfo[coord] == "object") { // Circular reference
+ cell.errors = SocialCalc.Constants.s_caccCircRef+startcoord; // set on original cell making the ref
+ checkinfo[startcoord] = true; // this one should be calculated once at this point
+ if (!recalcdata.firstcalc) {
+ recalcdata.firstcalc = startcoord;
+ }
+ else {
+ recalcdata.calclist[recalcdata.lastcalc] = startcoord;
+ }
+ recalcdata.lastcalc = startcoord;
+ recalcdata.calclistlength++; // count number on list
+ sheet.attribs.circularreferencecell = coord+"|"+oldcoord; // remember at least one circ ref
+ return cell.errors;
+ }
+ continue mainloop;
+ }
+
+ ttype = parseinfo[i].type; // get token details
+ ttext = parseinfo[i].text;
+ if (ttype == token_op) { // references with sheet specifier are not checked
+ if (ttext == "!") {
+ sheetref = true; // found a sheet reference
+ }
+ else if (ttext != ":") { // for everything but a range, reset
+ sheetref = false;
+ }
+ }
+
+ if (ttype == token_name) { // look for named range
+ value = scf.LookupName(sheet, ttext);
+ if (value.type == "range") { // only need to recurse here for range, which may be just one cell
+ pos = value.value.indexOf("|");
+ if (pos != -1) { // range - check each cell
+ coordvals.cr1 = SocialCalc.coordToCr(value.value.substring(0,pos));
+ pos2 = value.value.indexOf("|", pos+1);
+ coordvals.cr2 = SocialCalc.coordToCr(value.value.substring(pos+1,pos2));
+ coordvals.inrange = true;
+ coordvals.inrangestart = true;
+ i = i-1; // back up so will start up again here
+ continue;
+ }
+ }
+ else if (value.type == "coord") { // just a coord
+ ttype = token_coord; // treat as a coord inline
+ ttext = value.value; // and then drop through to next test which should succeed
+ }
+ else { // not a defined name - probably a function
+ }
+ }
+
+ if (ttype == token_coord) { // token is a coord
+
+ if (i >= 2 // look for a range
+ && parseinfo[i-1].type == token_op && parseinfo[i-1].text == ':'
+ && parseinfo[i-2].type == token_coord
+ && !sheetref) { // Range -- check each cell
+ coordvals.cr1 = SocialCalc.coordToCr(parseinfo[i-2].text); // remember range extents
+ coordvals.cr2 = SocialCalc.coordToCr(ttext);
+ coordvals.inrange = true; // next time use the range looping code
+ coordvals.inrangestart = true;
+ i = i-1; // back up so will start up again here
+ continue;
+ }
+
+ else if (!sheetref) { // Single cell reference
+ if (ttext.indexOf("$") != -1) ttext = ttext.replace(/\$/g, ""); // remove any $'s
+ coordvals.parsepos = i+1; // remember our position - come back on next token
+ coordvals.oldcoord = oldcoord; // remember back up chain
+ oldcoord = coord; // come back to us
+ coord = ttext;
+ if (checkinfo[coord] && typeof checkinfo[coord] == "object") { // Circular reference
+ cell.errors = SocialCalc.Constants.s_caccCircRef+startcoord; // set on original cell making the ref
+ checkinfo[startcoord] = true; // this one should be calculated once at this point
+ if (!recalcdata.firstcalc) { // add to calclist
+ recalcdata.firstcalc = startcoord;
+ }
+ else {
+ recalcdata.calclist[recalcdata.lastcalc] = startcoord;
+ }
+ recalcdata.lastcalc = startcoord;
+ recalcdata.calclistlength++; // count number on list
+ sheet.attribs.circularreferencecell = coord+"|"+oldcoord; // remember at least one circ ref
+ return cell.errors;
+ }
+ continue mainloop;
+ }
+ }
+ }
+
+ sheetref = false; // make sure off when bump back up
+
+ checkinfo[coord] = true; // this one is finished
+ if (!recalcdata.firstcalc) { // add to calclist
+ recalcdata.firstcalc = coord;
+ }
+ else {
+ recalcdata.calclist[recalcdata.lastcalc] = coord;
+ }
+ recalcdata.lastcalc = coord;
+ recalcdata.calclistlength++; // count number on list
+
+ coord = oldcoord; // go back to the formula that referred to us and continue
+ oldcoord = checkinfo[coord] ? checkinfo[coord].oldcoord : null;
+
+ }
+
+ return "";
+
+ }
+
+
+// *************************************
+//
+// Parse class:
+//
+// Used by ExecuteSheetCommand to get elements of commands to execute.
+// The string it works with consists of one or more lines each
+// made up of one or more tokens separated by a delimiter.
+//
+// *************************************
+
+// Initialize: set string to work with
+
+SocialCalc.Parse = function(str) {
+
+ // properties:
+
+ this.str = str;
+ this.pos = 0;
+ this.delimiter = " ";
+ this.lineEnd = str.indexOf("\n");
+ if (this.lineEnd < 0) {
+ this.lineEnd = str.length;
+ }
+
+ }
+
+// Return next token as a string
+
+SocialCalc.Parse.prototype.NextToken = function() {
+ if (this.pos < 0) return "";
+ var pos2 = this.str.indexOf(this.delimiter, this.pos);
+ var pos1 = this.pos;
+ if (pos2 > this.lineEnd) { // don't go past end of line
+ pos2 = this.lineEnd;
+ }
+ if (pos2 >= 0) {
+ this.pos = pos2 + 1;
+ return this.str.substring(pos1, pos2);
+ }
+ else {
+ this.pos = this.lineEnd;
+ return this.str.substring(pos1, this.lineEnd);
+ }
+ }
+
+// Return everything from current point until end of line
+
+SocialCalc.Parse.prototype.RestOfString = function() {
+ var oldpos = this.pos;
+ if (this.pos < 0 || this.pos >= this.lineEnd) return "";
+ this.pos = this.lineEnd;
+ return this.str.substring(oldpos, this.lineEnd);
+ }
+
+SocialCalc.Parse.prototype.RestOfStringNoMove = function() {
+ if (this.pos < 0 || this.pos >= this.lineEnd) return "";
+ return this.str.substring(this.pos, this.lineEnd);
+ }
+
+// Move current point to next line
+
+SocialCalc.Parse.prototype.NextLine = function() {
+ this.pos = this.lineEnd + 1;
+ this.lineEnd = this.str.indexOf("\n", this.pos);
+ if (this.lineEnd < 0) {
+ this.lineEnd = this.str.length;
+ }
+ }
+
+// Check to see if at end of string with no more to process
+
+SocialCalc.Parse.prototype.EOF = function() {
+ if (this.pos < 0 || this.pos >= this.str.length) return true;
+ return false;
+ }
+
+
+// *************************************
+//
+// UndoStack class:
+//
+// Implements the behavior needed for a normal application's undo/redo stack.
+// You add a new change sequence with PushChange.
+// The type argument is a string that can be used to lookup some general string
+// like "typing" or "setting attribute" for the menu prompts for undo/redo.
+//
+// You add the "do" steps with AddDo. The non-null, non-undefined arguments are
+// joined together with " " to make a command string to be saved.
+//
+// You add the undo steps as commands for the most recent change with AddUndo.
+// The non-null, non-undefined arguments are joined together with " " to make
+// a command string to be saved.
+//
+// The Undo and Redo functions move the Top Of Stack pointer through the changes stack
+// so you can undo and redo. Doing a new PushChange removes all undone items
+// after TOS.
+//
+// You can push more things than you can undo if you want.
+// There is a maximum to remember as the "did" stack for an audit trail (and as redo). This may be unlimited.
+// There is a separate maximum to remember that can be undone. This may be smaller than maxRedo.
+//
+// *************************************
+
+SocialCalc.UndoStack = function() {
+
+ // properties:
+
+ this.stack = []; // {command: [], type: type, undo: []} -- multiple dos and undos allowed
+ this.tos = -1; // top of stack position, used for undo/redo
+ this.maxRedo = 0; // Maximum size of redo stack (and audit trail which is this.stack[n].command) or zero if no limit
+ this.maxUndo = 50; // Maximum number of steps kept for undo (usually the memory intensive part) or zero if no limit
+
+ }
+
+SocialCalc.UndoStack.prototype.PushChange = function(type) { // adding a new thing to the stack
+ while (this.stack.length > 0 && this.stack.length-1 > this.tos) { // pop off things not redone
+ this.stack.pop();
+ }
+ this.stack.push({command: [], type: type, undo: []});
+ if (this.maxRedo && this.stack.length > this.maxRedo) { // limit number kept as audit trail
+ this.stack.shift(); // remove the extra one
+ }
+ if (this.maxUndo && this.stack.length > this.maxUndo) { // need to trim excess undo info
+ this.stack[this.stack.length - this.maxUndo - 1].undo = []; // only need to remove one
+ }
+ this.tos = this.stack.length - 1;
+ }
+
+SocialCalc.UndoStack.prototype.AddDo = function() {
+ var args = [];
+ for (var i=0; i<arguments.length; i++) {
+ if (arguments[i]!=null) args.push(arguments[i]); // ignore null or undefined
+ }
+ var cmd = args.join(" ");
+ this.stack[this.stack.length-1].command.push(cmd);
+ }
+
+SocialCalc.UndoStack.prototype.AddUndo = function() {
+ var args = [];
+ for (var i=0; i<arguments.length; i++) {
+ if (arguments[i]!=null) args.push(arguments[i]); // ignore null or undefined
+ }
+ var cmd = args.join(" ");
+ this.stack[this.stack.length-1].undo.push(cmd);
+ }
+
+SocialCalc.UndoStack.prototype.TOS = function() {
+ if (this.tos >= 0) return this.stack[this.tos];
+ else return null;
+ }
+
+SocialCalc.UndoStack.prototype.Undo = function() {
+ if (this.tos >= 0 && (!this.maxUndo || this.tos > this.stack.length - this.maxUndo - 1)) {
+ this.tos -= 1;
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+SocialCalc.UndoStack.prototype.Redo = function() {
+ if (this.tos < this.stack.length-1) {
+ this.tos += 1;
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+// *************************************
+//
+// Clipboard Object:
+//
+// This is a single object.
+// Stores the clipboard, which is shared by all active sheets.
+// Like the undo stack, it does not persist from one editing session to another.
+//
+// *************************************
+
+SocialCalc.Clipboard = {
+
+ // properties:
+
+ clipboard: "" // empty or string in save format with "copiedfrom:" set to a range
+
+ }
+
+
+// *************************************
+//
+// RenderContext class:
+//
+// *************************************
+
+SocialCalc.RenderContext = function(sheetobj) {
+
+ var parts, num, s;
+ var attribs = sheetobj.attribs;
+ var scc = SocialCalc.Constants;
+
+ // properties:
+
+ this.sheetobj = sheetobj;
+ this.hideRowsCols = false; // Rendering with panes only works with "false"
+ // !!!! Note: not implemented yet in rendering, just saved as an attribute
+ this.showGrid = false;
+ this.showRCHeaders = false;
+ this.rownamewidth = scc.defaultRowNameWidth;
+ this.pixelsPerRow = scc.defaultAssumedRowHeight;
+
+ this.cellskip = {}; // if present, coord of cell covering this cell
+ this.coordToCR = {}; // for cells starting spans, coordToCR[coord]={row:row, col:col}
+ this.colwidth = []; // precomputed column widths, taking into account defaults
+ this.totalwidth = 0; // precomputed total table width
+
+ this.rowpanes = []; // for each pane, {first: firstrow, last: lastrow}
+ this.colpanes = []; // for each pane, {first: firstrow, last: lastrow}
+ this.maxcol=0; // max col and row to display, adding long spans, etc.
+ this.maxrow=0;
+
+ this.highlights = {}; // for each cell with special display: coord:highlightType (see this.highlightTypes)
+ this.cursorsuffix = ""; // added to highlights[cr]=="cursor" to get type to lookup
+
+ this.highlightTypes = // attributes to change when highlit
+ {
+ cursor: {style: scc.defaultHighlightTypeCursorStyle, className: scc.defaultHighlightTypeCursorClass},
+ range: {style: scc.defaultHighlightTypeRangeStyle, className: scc.defaultHighlightTypeRangeClass},
+ cursorinsertup: {style: "color:#FFF;backgroundColor:#A6A6A6;backgroundRepeat:repeat-x;backgroundPosition:top left;backgroundImage:url("+scc.defaultImagePrefix+"cursorinsertup.gif);", className: scc.defaultHighlightTypeCursorClass},
+ cursorinsertleft: {style: "color:#FFF;backgroundColor:#A6A6A6;backgroundRepeat:repeat-y;backgroundPosition:top left;backgroundImage:url("+scc.defaultImagePrefix+"cursorinsertleft.gif);", className: scc.defaultHighlightTypeCursorClass},
+ range2: {style: "color:#000;backgroundColor:#FFF;backgroundImage:url("+scc.defaultImagePrefix+"range2.gif);", className: ""}
+ }
+
+ this.cellIDprefix = scc.defaultCellIDPrefix; // if non-null, each cell will render with an ID
+
+ this.defaultlinkstyle = null; // default linkstyle object (allows you to pass values to link renderer)
+ this.defaultHTMLlinkstyle = {type: "html"}; // default linkstyle for standalone HTML
+
+ // constants:
+
+ this.defaultfontstyle = scc.defaultCellFontStyle;
+ this.defaultfontsize = scc.defaultCellFontSize;
+ this.defaultfontfamily = scc.defaultCellFontFamily;
+
+ this.defaultlayout = scc.defaultCellLayout;
+
+ this.defaultpanedividerwidth = scc.defaultPaneDividerWidth;
+ this.defaultpanedividerheight = scc.defaultPaneDividerHeight;
+
+ this.gridCSS = scc.defaultGridCSS;
+
+ this.commentClassName = scc.defaultCommentClass; // for cells with non-blank comments when this.showGrid is true
+ this.commentCSS = scc.defaultCommentStyle; // any combination of classnames and styles may be used
+ this.commentNoGridClassName = scc.defaultCommentNoGridClass; // for cells when this.showGrid is false
+ this.commentNoGridCSS = scc.defaultCommentNoGridStyle; // any combination of classnames and styles may be used
+
+ this.classnames = // any combination of classnames and explicitStyles can be used
+ {
+ colname: scc.defaultColnameClass,
+ rowname: scc.defaultRownameClass,
+ selectedcolname: scc.defaultSelectedColnameClass,
+ selectedrowname: scc.defaultSelectedRownameClass,
+ upperleft: scc.defaultUpperLeftClass,
+ skippedcell: scc.defaultSkippedCellClass,
+ panedivider: scc.defaultPaneDividerClass
+ };
+
+ this.explicitStyles = // these may be used so you won't need a stylesheet with the classnames
+ {
+ colname: scc.defaultColnameStyle,
+ rowname: scc.defaultRownameStyle,
+ selectedcolname: scc.defaultSelectedColnameStyle,
+ selectedrowname: scc.defaultSelectedRownameStyle,
+ upperleft: scc.defaultUpperLeftStyle,
+ skippedcell: scc.defaultSkippedCellStyle,
+ panedivider: scc.defaultPaneDividerStyle
+ };
+
+ // processed info about cell skipping
+
+ this.cellskip = null;
+ this.needcellskip = true;
+
+ // precomputed values, filling in defaults indicated by "*"
+
+ this.fonts=[]; // for each fontnum, {style: fs, weight: fw, size: fs, family: ff}
+ this.layouts=[]; // for each layout, "padding:Tpx Rpx Bpx Lpx;vertical-align:va;"
+
+ this.needprecompute = true; // need to call PrecomputeSheetFontsAndLayouts
+
+ // if have a sheet object, initialize constants and precomputed values
+
+ if (sheetobj) {
+ this.rowpanes[0] = {first: 1, last: attribs.lastrow};
+ this.colpanes[0] = {first: 1, last: attribs.lastcol};
+
+ }
+ else throw scc.s_rcMissingSheet;
+
+ }
+
+// Methods:
+
+SocialCalc.RenderContext.prototype.PrecomputeSheetFontsAndLayouts = function() {SocialCalc.PrecomputeSheetFontsAndLayouts(this);};
+SocialCalc.RenderContext.prototype.CalculateCellSkipData = function() {SocialCalc.CalculateCellSkipData(this);};
+SocialCalc.RenderContext.prototype.CalculateColWidthData = function() {SocialCalc.CalculateColWidthData(this);};
+SocialCalc.RenderContext.prototype.SetRowPaneFirstLast = function(panenum, first, last) {this.rowpanes[panenum]={first:first, last:last};};
+SocialCalc.RenderContext.prototype.SetColPaneFirstLast = function(panenum, first, last) {this.colpanes[panenum]={first:first, last:last};};
+SocialCalc.RenderContext.prototype.CoordInPane = function(coord, rowpane, colpane) {return SocialCalc.CoordInPane(this, coord, rowpane, colpane);};
+SocialCalc.RenderContext.prototype.CellInPane = function(row, col, rowpane, colpane) {return SocialCalc.CellInPane(this, row, col, rowpane, colpane);};
+SocialCalc.RenderContext.prototype.InitializeTable = function(tableobj) {SocialCalc.InitializeTable(this, tableobj);};
+SocialCalc.RenderContext.prototype.RenderSheet = function(oldtable, linkstyle) {return SocialCalc.RenderSheet(this, oldtable, linkstyle);};
+SocialCalc.RenderContext.prototype.RenderColGroup = function() {return SocialCalc.RenderColGroup(this);};
+SocialCalc.RenderContext.prototype.RenderColHeaders = function() {return SocialCalc.RenderColHeaders(this);};
+SocialCalc.RenderContext.prototype.RenderSizingRow = function() {return SocialCalc.RenderSizingRow(this);};
+SocialCalc.RenderContext.prototype.RenderRow = function(rownum, rowpane, linkstyle) {return SocialCalc.RenderRow(this, rownum, rowpane, linkstyle);};
+SocialCalc.RenderContext.prototype.RenderSpacingRow = function() {return SocialCalc.RenderSpacingRow(this);};
+SocialCalc.RenderContext.prototype.RenderCell = function(rownum, colnum, rowpane, colpane, noElement, linkstyle)
+ {return SocialCalc.RenderCell(this, rownum, colnum, rowpane, colpane, noElement, linkstyle);};
+
+// Functions:
+
+SocialCalc.PrecomputeSheetFontsAndLayouts = function(context) {
+
+ var defaultfont, parts, layoutre, dparts, sparts, num, s, i;
+ var sheetobj = context.sheetobj;
+ var attribs = sheetobj.attribs;
+
+ if (attribs.defaultfont) {
+ defaultfont = sheetobj.fonts[attribs.defaultfont];
+ defaultfont = defaultfont.replace(/^\*/,SocialCalc.Constants.defaultCellFontStyle);
+ defaultfont = defaultfont.replace(/(.+)\*(.+)/,"$1"+SocialCalc.Constants.defaultCellFontSize+"$2");
+ defaultfont = defaultfont.replace(/\*$/,SocialCalc.Constants.defaultCellFontFamily);
+ parts=defaultfont.match(/^(\S+? \S+?) (\S+?) (\S.*)$/);
+ context.defaultfontstyle = parts[1];
+ context.defaultfontsize = parts[2];
+ context.defaultfontfamily = parts[3];
+ }
+
+ for (num=1; num<sheetobj.fonts.length; num++) { // precompute fonts by filling in the *'s
+ s=sheetobj.fonts[num];
+ s=s.replace(/^\*/,context.defaultfontstyle);
+ s=s.replace(/(.+)\*(.+)/,"$1"+context.defaultfontsize+"$2");
+ s=s.replace(/\*$/,context.defaultfontfamily);
+ parts=s.match(/^(\S+?) (\S+?) (\S+?) (\S.*)$/);
+ context.fonts[num] = {style: parts[1], weight: parts[2], size: parts[3], family: parts[4]};
+
+ }
+
+ layoutre = /^padding:\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+);vertical-align:\s*(\S+);/;
+ dparts = SocialCalc.Constants.defaultCellLayout.match(layoutre); // get built-in defaults
+
+ if (attribs.defaultlayout) {
+ sparts = sheetobj.layouts[attribs.defaultlayout].match(layoutre); // get sheet defaults, if set
+ }
+ else {
+ sparts = ["", "*", "*", "*", "*", "*"];
+ }
+
+ for (num=1; num<sheetobj.layouts.length; num++) { // precompute layouts by filling in the *'s
+ s=sheetobj.layouts[num];
+ parts = s.match(layoutre);
+ for (i=1; i<=5; i++) {
+ if (parts[i]=="*") {
+ parts[i] = (sparts[i] != "*" ? sparts[i] : dparts[i]); // if *, sheet default or built-in
+ }
+ }
+ context.layouts[num] = "padding:"+parts[1]+" "+parts[2]+" "+parts[3]+" "+parts[4]+
+ ";vertical-align:"+parts[5]+";";
+ }
+
+ context.needprecompute = false;
+
+ }
+
+SocialCalc.CalculateCellSkipData = function(context) {
+
+ var row, col, coord, cell, contextcell, colspan, rowspan, skiprow, skipcol, skipcoord;
+
+ var sheetobj=context.sheetobj;
+ var sheetrowattribs=sheetobj.rowattribs;
+ var sheetcolattribs=sheetobj.colattribs;
+ context.maxrow=0;
+ context.maxcol=0;
+ context.cellskip = {}; // reset
+
+ // Calculate cellskip data
+
+ for (row=1; row<=sheetobj.attribs.lastrow; row++) {
+ for (col=1; col<=sheetobj.attribs.lastcol; col++) { // look for spans and set cellskip for skipped cells
+ coord=SocialCalc.crToCoord(col, row);
+ cell=sheetobj.cells[coord];
+ // don't look at undefined cells (they have no spans) or skipped cells
+ if (cell===undefined || context.cellskip[coord]) continue;
+ colspan=cell.colspan || 1;
+ rowspan=cell.rowspan || 1;
+ if (colspan>1 || rowspan>1) {
+ for (skiprow=row; skiprow<row+rowspan; skiprow++) {
+ for (skipcol=col; skipcol<col+colspan; skipcol++) { // do the setting on individual cells
+ skipcoord=SocialCalc.crToCoord(skipcol,skiprow);
+ if (skipcoord==coord) { // for coord, remember row and col
+ context.coordToCR[coord]={row: row, col: col};
+ }
+ else { // for other cells, flag with coord of here
+ context.cellskip[skipcoord]=coord;
+ }
+ if (skiprow>context.maxrow) maxrow=skiprow;
+ if (skipcol>context.maxcol) maxcol=skipcol;
+ }
+ }
+ }
+ }
+ }
+
+ context.needcellskip = false;
+
+ }
+
+SocialCalc.CalculateColWidthData = function(context) {
+
+ var colnum, colname, colwidth, totalwidth;
+
+ var sheetobj=context.sheetobj;
+ var sheetcolattribs=sheetobj.colattribs;
+
+ // Calculate column width data
+
+ totalwidth=context.showRCHeaders ? context.rownamewidth-0 : 0;
+ for (colpane=0; colpane<context.colpanes.length; colpane++) {
+ for (colnum=context.colpanes[colpane].first; colnum<=context.colpanes[colpane].last; colnum++) {
+ colname=SocialCalc.rcColname(colnum);
+ colwidth = sheetobj.colattribs.width[colname] || sheetobj.attribs.defaultcolwidth || SocialCalc.Constants.defaultColWidth;
+ if (colwidth=="blank" || colwidth=="auto") colwidth="";
+ context.colwidth[colnum]=colwidth+"";
+ totalwidth+=(colwidth && ((colwidth-0)>0)) ? (colwidth-0) : 10;
+ }
+ }
+ context.totalwidth = totalwidth;
+
+ }
+
+SocialCalc.InitializeTable = function(context, tableobj) {
+
+/*
+
+Uses border-collapse so corners don't have holes
+Note: IE and Firefox handle <col> differently (IE adds borders and padding)
+under border-collapse and Safari has problems with <col> and wide text
+Tablelayout "fixed" also leads to problems
+
+*/
+
+/*
+
+*** Discussion ***
+
+The rendering assumes fixed column widths, even though SocialCalc allows "auto".
+There may be issues with "auto" and it is hard to make it work cross-browser
+with border-collapse, etc.
+
+This and the RenderSheet routine are where in the code the specifics of
+table attributes and column size definitions are set. As the browsers settle down
+and when we decide if we don't need auto width, we may want to revisit the way the
+code does this (e.g., use table-layout:fixed).
+
+*/
+ tableobj.style.borderCollapse="collapse";
+ tableobj.cellSpacing="0";
+ tableobj.cellPadding="0";
+
+ tableobj.style.width=context.totalwidth+"px";
+
+ }
+
+//
+// tableobj = SocialCalc.RenderSheet(context, oldtable, linkstyle)
+//
+// Renders a render context returning a DOM table object.
+// If there is an oldtable object, it replaces it in the parent node.
+// If oldtable is null, it just returns the new one.
+// The linkstyle is "" or null for editing rendering
+// and optionally an object passed on to formatting code.
+//
+
+SocialCalc.RenderSheet = function(context, oldtable, linkstyle) {
+
+ var newrow, rowpane;
+ var tableobj, colgroupobj, tbodyobj, parentnode;
+
+ // do precompute stuff if necessary
+
+ if (context.sheetobj.changedrendervalues) {
+ context.needcellskip = true;
+ context.needprecompute = true;
+ context.sheetobj.changedrendervalues = false;
+ }
+ if (context.needcellskip) {
+ context.CalculateCellSkipData();
+ }
+ if (context.needprecompute) {
+ context.PrecomputeSheetFontsAndLayouts();
+ }
+
+ context.CalculateColWidthData(); // always make sure col width values are up to date
+
+ // make the table element and fill it in
+
+ tableobj=document.createElement("table");
+ context.InitializeTable(tableobj);
+
+ colgroupobj=context.RenderColGroup();
+ tableobj.appendChild(colgroupobj);
+
+ tbodyobj=document.createElement("tbody");
+
+ tbodyobj.appendChild(context.RenderSizingRow());
+
+ if (context.showRCHeaders) {
+ newrow=context.RenderColHeaders();
+ if (newrow) tbodyobj.appendChild(newrow);
+ }
+
+ for (rowpane=0; rowpane<context.rowpanes.length; rowpane++) {
+ for (rownum=context.rowpanes[rowpane].first;rownum<=context.rowpanes[rowpane].last;rownum++) {
+ newrow=context.RenderRow(rownum, rowpane, linkstyle);
+ tbodyobj.appendChild(newrow);
+ }
+ if (rowpane<context.rowpanes.length-1) {
+ newrow=context.RenderSpacingRow();
+ tbodyobj.appendChild(newrow);
+ }
+ }
+
+ tableobj.appendChild(tbodyobj);
+
+ if (oldtable) {
+ parentnode = oldtable.parentNode;
+ if (parentnode) parentnode.replaceChild(tableobj, oldtable);
+ }
+
+ return tableobj;
+
+ }
+
+SocialCalc.RenderRow = function(context, rownum, rowpane, linkstyle) {
+
+ var sheetobj=context.sheetobj;
+
+ var result=document.createElement("tr");
+ var colnum, newcol, colpane, newdiv;
+
+ if (context.showRCHeaders) {
+ newcol=document.createElement("td");
+ if (context.classnames) newcol.className=context.classnames.rowname;
+ if (context.explicitStyles) newcol.style.cssText=context.explicitStyles.rowname;
+ newcol.width=context.rownamewidth;
+ newcol.style.verticalAlign="top"; // to get around Safari making top of centered row number be
+ // considered top of row (and can't get <row> position in Safari)
+ newcol.innerHTML=rownum+"";
+ result.appendChild(newcol);
+ }
+
+ for (colpane=0; colpane<context.colpanes.length; colpane++) {
+ for (colnum=context.colpanes[colpane].first; colnum<=context.colpanes[colpane].last; colnum++) {
+ newcol=context.RenderCell(rownum, colnum, rowpane, colpane, null, linkstyle);
+ if (newcol) result.appendChild(newcol);
+ }
+ if (colpane<context.colpanes.length-1) {
+ newcol=document.createElement("td");
+ newcol.width=context.defaultpanedividerwidth;
+ if (context.classnames.panedivider) newcol.className=context.classnames.panedivider;
+ if (context.explicitStyles.panedivider) newcol.style.cssText=context.explicitStyles.panedivider;
+ newdiv=document.createElement("div"); // for Firefox to avoid squishing
+ newdiv.style.width=context.defaultpanedividerwidth+"px";
+ newdiv.style.overflow="hidden";
+ newcol.appendChild(newdiv);
+ result.appendChild(newcol);
+ }
+ }
+ return result;
+ }
+
+SocialCalc.RenderSpacingRow = function(context) {
+
+ var colnum, newcol, colpane, w;
+
+ var sheetobj=context.sheetobj;
+
+ var result=document.createElement("tr");
+
+ if (context.showRCHeaders) {
+ newcol=document.createElement("td");
+ newcol.width=context.rownamewidth;
+ newcol.height=context.defaultpanedividerheight;
+ if (context.classnames.panedivider) newcol.className=context.classnames.panedivider;
+ if (context.explicitStyles.panedivider) newcol.style.cssText=context.explicitStyles.panedivider;
+ result.appendChild(newcol);
+ }
+
+ for (colpane=0; colpane<context.colpanes.length; colpane++) {
+ for (colnum=context.colpanes[colpane].first; colnum<=context.colpanes[colpane].last; colnum++) {
+ newcol=document.createElement("td");
+ w = context.colwidth[colnum];
+ if (w) newcol.width=w;
+ newcol.height=context.defaultpanedividerheight;
+ if (context.classnames.panedivider) newcol.className=context.classnames.panedivider;
+ if (context.explicitStyles.panedivider) newcol.style.cssText=context.explicitStyles.panedivider;
+ if (newcol) result.appendChild(newcol);
+ }
+ if (colpane<context.colpanes.length-1) {
+ newcol=document.createElement("td");
+ newcol.width=context.defaultpanedividerwidth;
+ newcol.height=context.defaultpanedividerheight;
+ if (context.classnames.panedivider) newcol.className=context.classnames.panedivider;
+ if (context.explicitStyles.panedivider) newcol.style.cssText=context.explicitStyles.panedivider;
+ result.appendChild(newcol);
+ }
+ }
+ return result;
+ }
+
+SocialCalc.RenderColHeaders = function(context) {
+
+ var sheetobj=context.sheetobj;
+
+ var result=document.createElement("tr");
+ var colnum, newcol;
+
+ if (!context.showRCHeaders) return null;
+
+ newcol=document.createElement("td");
+ if (context.classnames) newcol.className=context.classnames.upperleft;
+ if (context.explicitStyles) newcol.style.cssText=context.explicitStyles.upperleft;
+ newcol.width=context.rownamewidth;
+ result.appendChild(newcol);
+
+ for (colpane=0; colpane<context.colpanes.length; colpane++) {
+ for (colnum=context.colpanes[colpane].first; colnum<=context.colpanes[colpane].last; colnum++) {
+ newcol=document.createElement("td");
+ if (context.classnames) newcol.className=context.classnames.colname;
+ if (context.explicitStyles) newcol.style.cssText=context.explicitStyles.colname;
+ newcol.innerHTML=SocialCalc.rcColname(colnum);
+ result.appendChild(newcol);
+ }
+ if (colpane<context.colpanes.length-1) {
+ newcol=document.createElement("td");
+ newcol.width=context.defaultpanedividerwidth;
+ if (context.classnames.panedivider) newcol.className=context.classnames.panedivider;
+ if (context.explicitStyles.panedivider) newcol.style.cssText=context.explicitStyles.panedivider;
+ result.appendChild(newcol);
+ }
+ }
+ return result;
+ }
+
+SocialCalc.RenderColGroup = function(context) {
+
+ var colpane, colnum, newcol, t;
+ var sheetobj=context.sheetobj;
+
+ var result=document.createElement("colgroup");
+
+ if (context.showRCHeaders) {
+ newcol=document.createElement("col");
+ newcol.width=context.rownamewidth;
+ result.appendChild(newcol);
+ }
+
+ for (colpane=0; colpane<context.colpanes.length; colpane++) {
+ for (colnum=context.colpanes[colpane].first; colnum<=context.colpanes[colpane].last; colnum++) {
+ newcol=document.createElement("col");
+ t = context.colwidth[colnum];
+ if (t) newcol.width=t;
+ result.appendChild(newcol);
+ }
+ if (colpane<context.colpanes.length-1) {
+ newcol=document.createElement("col");
+ newcol.width=context.defaultpanedividerwidth;
+ result.appendChild(newcol);
+ }
+ }
+ return result;
+ }
+
+SocialCalc.RenderSizingRow = function(context) {
+
+ var colpane, colnum, newcell, t;
+ var sheetobj=context.sheetobj;
+
+ var result=document.createElement("tr");
+
+ if (context.showRCHeaders) {
+ newcell=document.createElement("td");
+ newcell.style.width=context.rownamewidth+"px";
+ newcell.height="1";
+ result.appendChild(newcell);
+ }
+
+ for (colpane=0; colpane<context.colpanes.length; colpane++) {
+ for (colnum=context.colpanes[colpane].first; colnum<=context.colpanes[colpane].last; colnum++) {
+ newcell=document.createElement("td");
+ t = context.colwidth[colnum];
+ if (t) newcell.width=t;
+ newcell.height="1";
+ result.appendChild(newcell);
+ }
+ if (colpane<context.colpanes.length-1) {
+ newcell=document.createElement("td");
+ newcell.width=context.defaultpanedividerwidth;
+ newcell.height="1";
+ result.appendChild(newcell);
+ }
+ }
+ return result;
+ }
+
+SocialCalc.RenderCell = function(context, rownum, colnum, rowpane, colpane, noElement, linkstyle) {
+
+ var sheetobj=context.sheetobj;
+
+ var num, t, result, span, stylename, cell, sheetattribs, scdefaults;
+ var stylestr="";
+
+ rownum = rownum-0; // make sure a number
+ colnum = colnum-0;
+
+ var coord=SocialCalc.crToCoord(colnum, rownum);
+
+ if (context.cellskip[coord]) { // skip if within a span
+ if (context.CoordInPane(context.cellskip[coord], rowpane, colpane)) {
+ return null; // span starts in this pane -- so just skip
+ }
+ result=noElement ? SocialCalc.CreatePseudoElement() : document.createElement("td"); // span start is scrolled away, so make a special cell
+ if (context.classnames.skippedcell) result.className=context.classnames.skippedcell;
+ if (context.explicitStyles.skippedcell) result.style.cssText=context.explicitStyles.skippedcell;
+ result.innerHTML="&nbsp;"; // put something there so height is OK
+ // !!! Really need to add borders in case there isn't anything else shown in the pane to get height
+ return result;
+ }
+
+ result=noElement ? SocialCalc.CreatePseudoElement() : document.createElement("td");
+
+ if (context.cellIDprefix) {
+ result.id = context.cellIDprefix+coord;
+ }
+
+ cell=sheetobj.cells[coord];
+
+ if (!cell) {
+ cell=new SocialCalc.Cell(coord);
+ }
+
+ sheetattribs=sheetobj.attribs;
+ scc=SocialCalc.Constants;
+
+ if (cell.colspan>1) {
+ span=1;
+ for (num=1; num<cell.colspan; num++) {
+ if (sheetobj.colattribs.hide[SocialCalc.rcColname(colnum+num)]!="yes" &&
+ context.CellInPane(rownum, colnum+num, rowpane, colpane)) {
+ span++;
+ }
+ }
+ result.colSpan=span;
+ }
+
+ if (cell.rowspan>1) {
+ span=1;
+ for (num=1; num<cell.rowspan; num++) {
+ if (sheetobj.rowattribs.hide[(rownum+num)+""]!="yes" &&
+ context.CellInPane(rownum+num, colnum, rowpane, colpane))
+ span++;
+ }
+ result.rowSpan=span;
+ }
+
+ if (cell.displaystring==undefined) { // cache the display value
+ cell.displaystring = SocialCalc.FormatValueForDisplay(sheetobj, cell.datavalue, coord, (linkstyle || context.defaultlinkstyle));
+ }
+ result.innerHTML = cell.displaystring;
+
+ num=cell.layout || sheetattribs.defaultlayout;
+ if (num) {
+ stylestr+=context.layouts[num]; // use precomputed layout with "*"'s filled in
+ }
+ else {
+ stylestr+=scc.defaultCellLayout;
+ }
+
+ num=cell.font || sheetattribs.defaultfont;
+ if (num) { // get expanded font strings in context
+ t = context.fonts[num]; // do each - plain "font:" style sets all sorts of other values, too (Safari font-stretch problem on cssText)
+ stylestr+="font-style:"+t.style+";font-weight:"+t.weight+";font-size:"+t.size+";font-family:"+t.family+";";
+ }
+ else {
+ if (scc.defaultCellFontSize) {
+ stylestr+="font-size:"+scc.defaultCellFontSize+";";
+ }
+ if (scc.defaultCellFontFamily) {
+ stylestr+="font-family:"+scc.defaultCellFontFamily+";";
+ }
+ }
+
+ num=cell.color || sheetattribs.defaultcolor;
+ if (num) stylestr+="color:"+sheetobj.colors[num]+";";
+
+ num=cell.bgcolor || sheetattribs.defaultbgcolor;
+ if (num) stylestr+="background-color:"+sheetobj.colors[num]+";";
+
+ num=cell.cellformat;
+ if (num) {
+ stylestr+="text-align:"+sheetobj.cellformats[num]+";";
+ }
+ else {
+ t=cell.valuetype.charAt(0);
+ if (t=="t") {
+ num=sheetattribs.defaulttextformat;
+ if (num) stylestr+="text-align:"+sheetobj.cellformats[num]+";";
+ }
+ else if (t="n") {
+ num=sheetattribs.defaultnontextformat;
+ if (num) {
+ stylestr+="text-align:"+sheetobj.cellformats[num]+";";
+ }
+ else {
+ stylestr+="text-align:right;";
+ }
+ }
+ else stylestr+="text-align:left;";
+ }
+
+ num=cell.bt;
+ if (num) stylestr+="border-top:"+sheetobj.borderstyles[num]+";";
+
+ num=cell.br;
+ if (num) stylestr+="border-right:"+sheetobj.borderstyles[num]+";";
+ else if (context.showGrid) {
+ if (context.CellInPane(rownum, colnum+(cell.colspan || 1), rowpane, colpane))
+ t=SocialCalc.crToCoord(colnum+(cell.colspan || 1), rownum);
+ else t="nomatch";
+ if (context.cellskip[t]) t=context.cellskip[t];
+ if (!sheetobj.cells[t] || !sheetobj.cells[t].bl)
+ stylestr+="border-right:"+context.gridCSS;
+ }
+
+ num=cell.bb;
+ if (num) stylestr+="border-bottom:"+sheetobj.borderstyles[num]+";";
+ else if (context.showGrid) {
+ if (context.CellInPane(rownum+(cell.rowspan || 1), colnum, rowpane, colpane))
+ t=SocialCalc.crToCoord(colnum, rownum+(cell.rowspan || 1));
+ else t="nomatch";
+ if (context.cellskip[t]) t=context.cellskip[t];
+ if (!sheetobj.cells[t] || !sheetobj.cells[t].bt)
+ stylestr+="border-bottom:"+context.gridCSS;
+ }
+
+ num=cell.bl;
+ if (num) stylestr+="border-left:"+sheetobj.borderstyles[num]+";";
+
+ if (cell.comment) {
+ if (context.showGrid) {
+ if (context.commentClassName) {
+ result.className = (result.className ? result.className+" " : "") + context.commentClassName;
+ }
+ stylestr+=context.commentCSS;
+ }
+ else {
+ if (context.commentNoGridClassName) {
+ result.className = (result.className ? result.className+" " : "") + context.commentNoGridClassName;
+ }
+ stylestr+=context.commentNoGridCSS;
+ }
+ }
+
+ result.style.cssText=stylestr;
+
+ //!!!!!!!!!
+ // NOTE: csss and cssc are not supported yet.
+ // csss needs to be parsed into pieces to override just the attributes specified, not all with assignment to cssText.
+ // cssc just needs to set the className.
+
+ t = context.highlights[coord];
+ if (t) { // this is a highlit cell: Override style appropriately
+ if (t=="cursor") t += context.cursorsuffix; // cursor can take alternative forms
+ if (context.highlightTypes[t].className) {
+ result.className = (result.className ? result.className+" " : "") + context.highlightTypes[t].className;
+ }
+ SocialCalc.setStyles(result, context.highlightTypes[t].style);
+ }
+
+ return result;
+ }
+
+SocialCalc.CoordInPane = function(context, coord, rowpane, colpane) {
+ var coordToCR = context.coordToCR[coord];
+ if (!coordToCR || !coordToCR.row || !coordToCR.col) throw "Bad coordToCR for "+coord;
+ return context.CellInPane(coordToCR.row, coordToCR.col, rowpane, colpane);
+ }
+
+
+SocialCalc.CellInPane = function(context, row, col, rowpane, colpane) {
+ var panerowlimits = context.rowpanes[rowpane];
+ var panecollimits = context.colpanes[colpane];
+ if (!panerowlimits || !panecollimits) throw "CellInPane called with unknown panes "+rowpane+"/"+colpane;
+ if (row < panerowlimits.first || row > panerowlimits.last) return false;
+ if (col < panecollimits.first || col > panecollimits.last) return false;
+ return true;
+ }
+
+SocialCalc.CreatePseudoElement = function() {
+ return {style:{cssText:""}, innerHTML: "", className: ""};
+ }
+
+
+// *************************************
+//
+// Misc. functions:
+//
+// *************************************
+
+SocialCalc.rcColname = function(c) {
+ if (c > 702) c = 702; // maximum number of columns - ZZ
+ if (c < 1) c = 1;
+ var collow = (c - 1) % 26 + 65;
+ var colhigh = Math.floor((c - 1) / 26);
+ if (colhigh)
+ return String.fromCharCode(colhigh + 64) + String.fromCharCode(collow);
+ else
+ return String.fromCharCode(collow);
+ }
+
+SocialCalc.letters = ["A","B","C","D","E","F","G","H","I","J","K","L","M",
+ "N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
+
+SocialCalc.crToCoord = function(c, r) {
+ var result;
+ if (c < 1) c = 1;
+ if (c > 702) c = 702; // maximum number of columns - ZZ
+ if (r < 1) r = 1;
+ var collow = (c - 1) % 26;
+ var colhigh = Math.floor((c - 1) / 26);
+ if (colhigh)
+ result = SocialCalc.letters[colhigh-1] + SocialCalc.letters[collow] + r;
+ else
+ result = SocialCalc.letters[collow] + r;
+ return result;
+ }
+
+SocialCalc.coordToCol = {}; // too expensive to set in crToCoord since that is called so many times
+SocialCalc.coordToRow = {};
+
+SocialCalc.coordToCr = function(cr) {
+ var c, i, ch;
+ var r = SocialCalc.coordToRow[cr];
+ if (r) return {row: r, col: SocialCalc.coordToCol[cr]};
+ c=0;r=0;
+ for (i=0; i<cr.length; i++) { // this was faster than using regexes; assumes well-formed
+ ch = cr.charCodeAt(i);
+ if (ch==36) ; // skip $'s
+ else if (ch<=57) r = 10*r + ch-48;
+ else if (ch>=97) c = 26*c + ch-96;
+ else if (ch>=65) c = 26*c + ch-64;
+ }
+ SocialCalc.coordToCol[cr] = c;
+ SocialCalc.coordToRow[cr] = r;
+ return {row: r, col: c};
+
+ }
+
+SocialCalc.ParseRange = function(range) {
+ var pos, cr, cr1, cr2;
+ if (!range) range = "A1:A1"; // error return, hopefully benign
+ range = range.toUpperCase();
+ pos = range.indexOf(":");
+ if (pos>=0) {
+ cr = range.substring(0,pos);
+ cr1 = SocialCalc.coordToCr(cr);
+ cr1.coord = cr;
+ cr = range.substring(pos+1);
+ cr2 = SocialCalc.coordToCr(cr);
+ cr2.coord = cr;
+ }
+ else {
+ cr1 = SocialCalc.coordToCr(range);
+ cr1.coord = range;
+ cr2 = SocialCalc.coordToCr(range);
+ cr2.coord = range;
+ }
+ return {cr1: cr1, cr2: cr2};
+ }
+
+SocialCalc.decodeFromSave = function(s) {
+ if (typeof s != "string") return s;
+ if (s.indexOf("\\")==-1) return s; // for performace reasons: replace nothing takes up time
+ var r=s.replace(/\\c/g,":");
+ r=r.replace(/\\n/g,"\n");
+ return r.replace(/\\b/g,"\\");
+ }
+
+SocialCalc.decodeFromAjax = function(s) {
+ if (typeof s != "string") return s;
+ if (s.indexOf("\\")==-1) return s; // for performace reasons: replace nothing takes up time
+ var r=s.replace(/\\c/g,":");
+ r=r.replace(/\\n/g,"\n");
+ r=r.replace(/\\e/g,"]]");
+ return r.replace(/\\b/g,"\\");
+ }
+
+SocialCalc.encodeForSave = function(s) {
+ if (typeof s != "string") return s;
+ if (s.indexOf("\\")!=-1) // for performace reasons: replace nothing takes up time
+ s=s.replace(/\\/g,"\\b");
+ if (s.indexOf(":")!=-1)
+ s=s.replace(/:/g,"\\c");
+ if (s.indexOf("\n")!=-1)
+ s=s.replace(/\n/g,"\\n");
+ return s;
+ }
+
+//
+// Returns estring where &, <, >, " are HTML escaped
+//
+SocialCalc.special_chars = function(string) {
+
+ if (/[&|<|>|"]/.test(string)) { // only do "slow" replaces if something to replace
+ string = string.replace(/&/g, "&amp;");
+ string = string.replace(/</g, "&lt;");
+ string = string.replace(/>/g, "&gt;");
+ string = string.replace(/"/g, "&quot;");
+ }
+ return string;
+
+ }
+
+SocialCalc.Lookup = function(value, list) {
+
+ for (i=0; i<list.length; i++) {
+ if (list[i] > value) {
+ if (i>0) return i-1;
+ else return null;
+ }
+ }
+ return list.length-1; // if all smaller, matches last
+
+ }
+
+//
+// setStyles(element, cssText)
+//
+// Takes a pseudo style string (e.g., text-align must be textAlign) and sets
+// the element's style value for each style name listed (leaving others unchanged).
+// OK to call with null cssText.
+//
+
+SocialCalc.setStyles = function (element, cssText) {
+
+ var parts, part, pos, name, value;
+
+ if (!cssText) return;
+
+ parts = cssText.split(";");
+ for (part=0; part<parts.length; part++) {
+ pos = parts[part].indexOf(":"); // find first colon (could be one in url)
+ if (pos != -1) {
+ name = parts[part].substring(0, pos);
+ value = parts[part].substring(pos+1);
+ if (name && value) { // if non-null name and value, set style
+ element.style[name] = value;
+ }
+ }
+// namevalue = parts[part].split(":");
+// if (namevalue[0]) element.style[namevalue[0]] = namevalue[1];
+ }
+
+ }
+
+//
+// GetViewportInfo() - returns object with viewport width and height, and scroll offsets
+//
+// Flanagan, JavaScript, 5th Edition, page 276
+//
+
+SocialCalc.GetViewportInfo = function () {
+
+ var result = {};
+
+ if (window.innerWidth) { // all but IE
+ result.width = window.innerWidth;
+ result.height = window.innerHeight;
+ result.horizontalScroll = window.pageXOffset;
+ result.verticalScroll = window.pageYOffset;
+ }
+ else {
+ if (document.documentElement && document.documentElement.clientWidth) {
+ result.width = document.documentElement.clientWidth;
+ result.height = document.documentElement.clientHeight;
+ result.horizontalScroll = document.documentElement.scrollLeft;
+ result.verticalScroll = document.documentElement.scrollTop;
+ }
+ else if (document.body.clientWidth) {
+ result.width = document.body.clientWidth;
+ result.height = document.body.clientHeight;
+ result.horizontalScroll = document.body.scrollLeft;
+ result.verticalScroll = document.body.scrollTop;
+ }
+ }
+
+ return result;
+ }
+
+//
+// GetElementPosition(element) - returns object with left and top position of the element in the document
+//
+// Goodman's JavaScript & DHTML Cookbook, 2nd Edition, page 415
+//
+
+SocialCalc.GetElementPosition = function (element) {
+
+ var offsetLeft = 0;
+ var offsetTop = 0;
+ while (element) {
+ offsetLeft+=element.offsetLeft;
+ offsetTop+=element.offsetTop;
+ element=element.offsetParent;
+ }
+ return {left:offsetLeft, top:offsetTop};
+
+ }
+
+//
+// GetElementPositionWithScroll(element) - returns object with left and top position of the element in the document
+//
+// Takes into account scroll offsets by going through entire tree
+//
+
+SocialCalc.GetElementPositionWithScroll = function (element) {
+
+ var offsetLeft = 0;
+ var offsetTop = 0;
+ var offsetElement = element;
+ while (element) {
+ if (element.tagName=="HTML") break;
+ if (element == offsetElement) {
+ offsetLeft+=element.offsetLeft;
+ offsetTop+=element.offsetTop;
+ offsetElement = element.offsetParent;
+ }
+ if (element.scrollLeft) {
+ offsetLeft-=element.scrollLeft;
+ }
+ if (element.scrollTop) {
+ offsetTop-=element.scrollTop;
+ }
+ element=element.parentNode;
+ }
+ return {left:offsetLeft, top:offsetTop};
+
+ }
+
+//
+// LookupElement(element, array) - returns array element which is an object with "element" of element
+//
+
+SocialCalc.LookupElement = function (element, array) {
+
+ var i;
+ for (i=0; i<array.length; i++) {
+ if (array[i].element == element) return array[i];
+ }
+ return null;
+
+ }
+
+//
+// AssignID(obj, element, id) - Optionally assigns an ID with a prefix to the element
+//
+
+SocialCalc.AssignID = function (obj, element, id) {
+
+ if (obj.idPrefix) { // Object must have a non-empty idPrefix attribute
+ element.id = obj.idPrefix + id;
+ }
+
+ }
+
+//
+// SocialCalc.GetCellContents(sheetobj, coord)
+//
+// Returns the contents (value, formula, constant, etc.) of a cell
+// with appropriate prefix ("'", "=", etc.)
+//
+
+SocialCalc.GetCellContents = function(sheetobj, coord) {
+
+ var result = "";
+ var cellobj = sheetobj.cells[coord];
+ if (cellobj) {
+ switch (cellobj.datatype) {
+ case "v":
+ result = cellobj.datavalue+"";
+ break;
+ case "t":
+ result = "'"+cellobj.datavalue;
+ break;
+ case "f":
+ result = "="+cellobj.formula;
+ break;
+ case "c":
+ result = cellobj.formula;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return result;
+
+ }
+
+//
+// Routines translated from the SocialCalc 1.1.0 Perl code:
+//
+// (Makes use of the FormatNumber JavaScript code translated from the Perl.)
+//
+
+//
+// displayvalue = FormatValueForDisplay(sheetobj, value, cr, linkstyle)
+//
+// Returns a string, in HTML, for the contents of a cell.
+//
+// The value is a either numeric or text, the cr is the coord of the cell
+// (its cell properties are used to determine formatting), and linkstyle
+// is a value passed to wiki-text expansion routines specifying the
+// purpose of the rendering so, for example, links can be rendered differently
+// during edit than with plain HTML.
+//
+
+SocialCalc.FormatValueForDisplay = function(sheetobj, value, cr, linkstyle) {
+
+ var valueformat, has_parens, has_commas, valuetype, valuesubtype;
+ var displayvalue;
+
+ var sheetattribs=sheetobj.attribs;
+ var scc=SocialCalc.Constants;
+
+ var cell=sheetobj.cells[cr];
+
+ if (!cell) { // get an empty cell if not there
+ cell=new SocialCalc.Cell(cr);
+ }
+
+ displayvalue = value;
+
+ valuetype = cell.valuetype || ""; // get type of value to determine formatting
+ valuesubtype = valuetype.substring(1);
+ valuetype = valuetype.charAt(0);
+
+ if (cell.errors || valuetype=="e") {
+ displayvalue = cell.errors || valuesubtype || "Error in cell";
+ return displayvalue;
+ }
+
+ if (valuetype=="t") {
+ valueformat = sheetobj.valueformats[cell.textvalueformat-0] || sheetobj.valueformats[sheetattribs.defaulttextvalueformat-0] || "";
+ if (valueformat=="formula") {
+ if (cell.datatype=="f") {
+ displayvalue = SocialCalc.special_chars("="+cell.formula) || "&nbsp;";
+ }
+ else if (cell.datatype=="c") {
+ displayvalue = SocialCalc.special_chars("'"+cell.formula) || "&nbsp;";
+ }
+ else {
+ displayvalue = SocialCalc.special_chars("'"+displayvalue) || "&nbsp;";
+ }
+ return displayvalue;
+ }
+ displayvalue = SocialCalc.format_text_for_display(displayvalue, cell.valuetype, valueformat, sheetobj, linkstyle);
+ }
+
+ else if (valuetype=="n") {
+ valueformat = cell.nontextvalueformat;
+ if (valueformat==null || valueformat=="") { //
+ valueformat = sheetattribs.defaultnontextvalueformat;
+ }
+ valueformat = sheetobj.valueformats[valueformat-0];
+ if (valueformat==null || valueformat=="none") {
+ valueformat = "";
+ }
+ if (valueformat=="formula") {
+ if (cell.datatype=="f") {
+ displayvalue = SocialCalc.special_chars("="+cell.formula) || "&nbsp;";
+ }
+ else if (cell.datatype=="c") {
+ displayvalue = SocialCalc.special_chars("'"+cell.formula) || "&nbsp;";
+ }
+ else {
+ displayvalue = SocialCalc.special_chars("'"+displayvalue) || "&nbsp;";
+ }
+ return displayvalue;
+ }
+ else if (valueformat=="forcetext") {
+ if (cell.datatype=="f") {
+ displayvalue = SocialCalc.special_chars("="+cell.formula) || "&nbsp;";
+ }
+ else if (cell.datatype=="c") {
+ displayvalue = SocialCalc.special_chars(cell.formula) || "&nbsp;";
+ }
+ else {
+ displayvalue = SocialCalc.special_chars(displayvalue) || "&nbsp;";
+ }
+ return displayvalue;
+ }
+
+ displayvalue = SocialCalc.format_number_for_display(displayvalue, cell.valuetype, valueformat);
+
+ }
+ else { // unknown type - probably blank
+ displayvalue = "&nbsp;";
+ }
+
+ return displayvalue;
+
+ }
+
+
+//
+// displayvalue = format_text_for_display(rawvalue, valuetype, valueformat, sheetobj, linkstyle)
+//
+
+SocialCalc.format_text_for_display = function(rawvalue, valuetype, valueformat, sheetobj, linkstyle) {
+
+ var valueformat, valuesubtype, dvsc, dvue, textval;
+ var displayvalue;
+
+ valuesubtype = valuetype.substring(1);
+
+ displayvalue = rawvalue;
+
+ if (valueformat=="none" || valueformat==null) valueformat="";
+ if (!/^(text-|custom|hidden)/.test(valueformat)) valueformat="";
+ if (valueformat=="" || valueformat=="General") { // determine format from type
+ if (valuesubtype=="h") valueformat="text-html";
+ if (valuesubtype=="w") valueformat="text-wiki";
+ if (valuesubtype=="l") valueformat="text-link";
+ if (!valuesubtype) valueformat="text-plain";
+ }
+ if (valueformat=="text-html") { // HTML - output as it as is
+ ;
+ }
+ else if (SocialCalc.Callbacks.expand_wiki && /^text-wiki/.test(valueformat)) { // do general wiki markup
+ displayvalue = SocialCalc.Callbacks.expand_wiki(displayvalue, sheetobj, linkstyle, valueformat);
+ }
+ else if (valueformat=="text-wiki") { // wiki text
+ displayvalue = (SocialCalc.Callbacks.expand_markup
+ && SocialCalc.Callbacks.expand_markup(displayvalue, sheetobj, linkstyle)) || // do old wiki markup
+ SocialCalc.special_chars("wiki-text:"+displayvalue);
+ }
+ else if (valueformat=="text-url") { // text is a URL for a link
+ dvsc = SocialCalc.special_chars(displayvalue);
+ dvue = encodeURI(displayvalue);
+ displayvalue = '<a href="'+dvue+'">'+dvsc+'</a>';
+ }
+ else if (valueformat=="text-link") { // more extensive link capabilities for regular web links
+ displayvalue = SocialCalc.expand_text_link(displayvalue, sheetobj, linkstyle, valueformat);
+ }
+ else if (valueformat=="text-image") { // text is a URL for an image
+ dvue = encodeURI(displayvalue);
+ displayvalue = '<img src="'+dvue+'">';
+ }
+ else if (valueformat.substring(0,12)=="text-custom:") { // construct a custom text format: @r = text raw, @s = special chars, @u = url encoded
+ dvsc = SocialCalc.special_chars(displayvalue); // do special chars
+ dvsc = dvsc.replace(/ /g, "&nbsp; "); // keep multiple spaces
+ dvsc = dvsc.replace(/\n/g, "<br>"); // keep line breaks
+ dvue = encodeURI(displayvalue);
+ textval={};
+ textval.r = displayvalue;
+ textval.s = dvsc;
+ textval.u = dvue;
+ displayvalue = valueformat.substring(12); // remove "text-custom:"
+ displayvalue = displayvalue.replace(/@(r|s|u)/g, function(a,c){return textval[c];}); // replace placeholders
+ }
+ else if (valueformat.substring(0,6)=="custom") { // custom
+ displayvalue = SocialCalc.special_chars(displayvalue); // do special chars
+ displayvalue = displayvalue.replace(/ /g, "&nbsp; "); // keep multiple spaces
+ displayvalue = displayvalue.replace(/\n/g, "<br>"); // keep line breaks
+ displayvalue += " (custom format)";
+ }
+ else if (valueformat=="hidden") {
+ displayvalue = "&nbsp;";
+ }
+ else { // plain text
+ displayvalue = SocialCalc.special_chars(displayvalue); // do special chars
+ displayvalue = displayvalue.replace(/ /g, "&nbsp; "); // keep multiple spaces
+ displayvalue = displayvalue.replace(/\n/g, "<br>"); // keep line breaks
+ }
+
+ return displayvalue;
+
+ }
+
+
+//
+// displayvalue = format_number_for_display(rawvalue, valuetype, valueformat)
+//
+
+SocialCalc.format_number_for_display = function(rawvalue, valuetype, valueformat) {
+
+ var value, valuesubtype;
+ var scc = SocialCalc.Constants;
+
+ value = rawvalue-0;
+
+ valuesubtype = valuetype.substring(1);
+
+ if (valueformat=="Auto" || valueformat=="") { // cases with default format
+ if (valuesubtype=="%") { // will display a % character
+ valueformat = "#,##0.0%";
+ }
+ else if (valuesubtype=='$') {
+ valueformat = '[$]#,##0.00';
+ }
+ else if (valuesubtype=='dt') {
+ valueformat = scc.defaultFormatdt;
+ }
+ else if (valuesubtype=='d') {
+ valueformat = scc.defaultFormatd;
+ }
+ else if (valuesubtype=='t') {
+ valueformat = scc.defaultFormatt;
+ }
+ else if (valuesubtype=='l') {
+ valueformat = 'logical';
+ }
+ else {
+ valueformat = "General";
+ }
+ }
+
+ if (valueformat=="logical") { // do logical format
+ return value ? scc.defaultDisplayTRUE : scc.defaultDisplayFALSE;
+ }
+
+ if (valueformat=="hidden") { // do hidden format
+ return "&nbsp;";
+ }
+
+ // Use format
+
+ return SocialCalc.FormatNumber.formatNumberWithFormat(rawvalue, valueformat, "");
+
+ }
+
+//
+// valueinfo = DetermineValueType(rawvalue)
+//
+// Takes a value and looks for special formatting like $, %, numbers, etc.
+// Returns the value as a number or string and the type as {value: value, type: type}.
+// Tries to follow the spec for spreadsheet function VALUE(v).
+//
+
+SocialCalc.DetermineValueType = function(rawvalue) {
+
+ var value = rawvalue + "";
+ var type = "t";
+ var tvalue, matches, year, hour, minute, second, denom, num, intgr, constr;
+
+ tvalue = value.replace(/^\s+/, ""); // remove leading and trailing blanks
+ tvalue = tvalue.replace(/\s+$/, "");
+
+ if (value.length==0) {
+ type = "";
+ }
+ else if (value.match(/^\s+$/)) { // just blanks
+ ; // leave type "t"
+ }
+ else if (tvalue.match(/^[-+]?\d*(?:\.)?\d*(?:[eE][-+]?\d+)?$/)) { // general number, including E
+ value = tvalue - 0; // try converting to number
+ if (isNaN(value)) { // leave alone - catches things like plain "-"
+ value = rawvalue + "";
+ }
+ else {
+ type = "n";
+ }
+ }
+ else if (tvalue.match(/^[-+]?\d*(?:\.)?\d*\s*%$/)) { // percent form: 15.1%
+ value = (tvalue.slice(0, -1) - 0) / 100; // convert and scale
+ type = "n%";
+ }
+ else if (tvalue.match(/^[-+]?\$\s*\d*(?:\.)?\d*\s*$/) && tvalue.match(/\d/)) { // $ format: $1.49
+ value = tvalue.replace(/\$/, "") - 0;
+ type = "n$";
+ }
+ else if (tvalue.match(/^[-+]?(\d*,\d*)+(?:\.)?\d*$/)) { // number format ignoring commas: 1,234.49
+ value = tvalue.replace(/,/g, "") - 0;
+ type = "n";
+ }
+ else if (tvalue.match(/^[-+]?(\d*,\d*)+(?:\.)?\d*\s*%$/)) { // % with commas: 1,234.49%
+ value = (tvalue.replace(/[%,]/g, "") - 0) / 100;
+ type = "n%";
+ }
+ else if (tvalue.match(/^[-+]?\$\s*(\d*,\d*)+(?:\.)?\d*$/) && tvalue.match(/\d/)) { // $ and commas: $1,234.49
+ value = tvalue.replace(/[\$,]/g, "") - 0;
+ type = "n$";
+ }
+ else if (matches=value.match(/^(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{1,4})\s*$/)) { // MM/DD/YYYY, MM/DD/YYYY
+ year = matches[3] - 0;
+ year = year < 1000 ? year + 2000 : year;
+ value = SocialCalc.FormatNumber.convert_date_gregorian_to_julian(year, matches[1]-0, matches[2]-0)-2415019;
+ type = "nd";
+ }
+ else if (matches=value.match(/^(\d{4})[\/\-](\d{1,2})[\/\-](\d{1,2})\s*$/)) { // YYYY-MM-DD, YYYY/MM/DD
+ year = matches[1]-0;
+ year = year < 1000 ? year + 2000 : year;
+ value = SocialCalc.FormatNumber.convert_date_gregorian_to_julian(year, matches[2]-0, matches[3]-0)-2415019;
+ type = "nd";
+ }
+ else if (matches=value.match(/^(\d{1,2}):(\d{1,2})\s*$/)) { // HH:MM
+ hour = matches[1]-0;
+ minute = matches[2]-0;
+ if (hour < 24 && minute < 60) {
+ value = hour/24 + minute/(24*60);
+ type = "nt";
+ }
+ }
+ else if (matches=value.match(/^(\d{1,2}):(\d{1,2}):(\d{1,2})\s*$/)) { // HH:MM:SS
+ hour = matches[1]-0;
+ minute = matches[2]-0;
+ second = matches[3]-0;
+ if (hour < 24 && minute < 60 && second < 60) {
+ value = hour/24 + minute/(24*60) + second/(24*60*60);
+ type = "nt";
+ }
+ }
+ else if (matches=value.match(/^\s*([-+]?\d+) (\d+)\/(\d+)\s*$/)) { // 1 1/2
+ intgr = matches[1]-0;
+ num = matches[2]-0;
+ denom = matches[3]-0;
+ if (denom && denom > 0) {
+ value = intgr + (intgr < 0 ? -num/denom : num/denom);
+ type = "n";
+ }
+ }
+ else if (constr=SocialCalc.InputConstants[value.toUpperCase()]) { // special constants, like "false" and #N/A
+ num = constr.indexOf(",");
+ value = constr.substring(0,num)-0;
+ type = constr.substring(num+1);
+ }
+
+ else if (tvalue.length > 7 && tvalue.substring(0,7).toLowerCase()=="http://") { // URL
+ value = tvalue;
+ type = "tl";
+ }
+
+ return {value: value, type: type};
+
+ }
+
+SocialCalc.InputConstants = { // strings that turn into constants for SocialCalc.DetermineValueType
+ "TRUE": "1,nl", "FALSE": "0,nl", "#N/A": "0,e#N/A", "#NULL!": "0,e#NULL!", "#NUM!": "0,e#NUM!",
+ "#DIV/0!": "0,e#DIV/0!", "#VALUE!": "0,e#VALUE!", "#REF!": "0,e#REF!", "#NAME?": "0,e#NAME?"};
+
+//
+// result = default_expand_markup(displayvalue, sheetobj, linkstyle)
+//
+// Processes wiki-text -- this is a placeholder.
+// Reference to here in SocialCalc.expand_markup should be replaced by application-specific routine.
+//
+
+SocialCalc.default_expand_markup = function(displayvalue, sheetobj, linkstyle) {
+
+ var result = displayvalue;
+
+ result = SocialCalc.special_chars(result); // do special chars
+ result = result.replace(/ /g, "&nbsp; "); // keep multiple spaces
+ result = result.replace(/\n/g, "<br>"); // keep line breaks
+
+ return result; // do very little by default
+
+ result = result.replace(/('*)'''(.*?)'''/g, "$1<b>$2<\/b>"); // Wiki-style bold/italics
+ result = result.replace(/''(.*?)''/g, "<i>$1<\/i>");
+
+ return result;
+
+ }
+
+
+//
+// result = SocialCalc.expand_text_link(displayvalue, sheetobj, linkstyle, valueformat)
+//
+// Parses link text (URL, descriptions, pagenames, workspace names) and returns HTML
+//
+
+SocialCalc.expand_text_link = function(displayvalue, sheetobj, linkstyle, valueformat) {
+
+ var desc, tb, str;
+
+ var scc = SocialCalc.Constants;
+
+ var url = "";
+ var parts = SocialCalc.ParseCellLinkText(displayvalue+"");
+
+ if (parts.desc) {
+ desc = SocialCalc.special_chars(parts.desc);
+ }
+ else {
+ desc = parts.pagename ? scc.defaultPageLinkFormatString : scc.defaultLinkFormatString;
+ }
+
+ if (displayvalue.length > 7 && displayvalue.substring(0,7).toLowerCase()=="http://"
+ && displayvalue.charAt(displayvalue.length-1)!=">") {
+ desc = desc.substring(7); // remove http:// unless explicit
+ }
+
+ tb = (parts.newwin || !linkstyle) ? ' target="_blank"' : "";
+
+ if (parts.pagename) {
+ if (SocialCalc.Callbacks.MakePageLink) {
+ url = SocialCalc.Callbacks.MakePageLink(parts.pagename, parts.workspacename, linkstyle, valueformat);
+ }
+// else if (parts.workspace) {
+// url = "/" + encodeURI(parts.workspace) + "/" + encodeURI(parts.pagename);
+// }
+// else {
+// url = parts.pagename;
+// }
+ }
+ else {
+ url = encodeURI(parts.url);
+ }
+ str = '<a href="' + url + '"' + tb + '>' + desc + '</a>';
+
+ return str;
+
+ }
+
+
+//
+// result = SocialCalc.ParseCellLinkText(str)
+//
+// Given: url = http://www.someurl.com/more, desc = Some descriptive text
+//
+// Takes the following:
+//
+// url
+// <url>
+// desc<url>
+// "desc"<url>
+// <<>> instead of <> => target="_blank" (new window)
+//
+// [page name]
+// "desc"[page name]
+// desc[page name]
+// {workspace name [page name]}
+// "desc"{workspace name [page name]}
+// [[]] instead of [] => target="_blank" (new window)
+//
+//
+// Returns: {url: url, desc: desc, newwin: t/f, pagename: pagename, workspace: workspace}
+//
+
+SocialCalc.ParseCellLinkText = function(str) {
+
+ var result = {url: "", desc: "", newwin: false, pagename: "", workspace: ""};
+
+ var pageform = false;
+ var urlend = str.length - 1;
+ var descstart = 0;
+ var lastlt = str.lastIndexOf("<");
+ var lastbrkt = str.lastIndexOf("[");
+ var lastbrace = str.lastIndexOf("{");
+ var descend = -1;
+
+ if ((str.charAt(urlend) != ">" || lastlt == -1)
+ && (str.charAt(urlend) != "]" || lastbrkt == -1)
+ && (str.charAt(urlend) != "}" || str.charAt(urlend-1) != "]" ||
+ lastbrace == -1 || lastbrkt == -1 || lastbrkt < lastbrace)) { // plain url
+ urlend++;
+ descend = urlend;
+ }
+ else { // some markup
+ if (str.charAt(urlend)==">") { // url form
+ descend = lastlt - 1;
+ if (lastlt > 0 && str.charAt(descend) == "<" && str.charAt(urlend-1) == ">") {
+ descend--;
+ urlend--;
+ result.newwin = true;
+ }
+ }
+
+ else if (str.charAt(urlend)=="]") { // plain page form
+ descend = lastbrkt - 1;
+ pageform = true;
+ if (lastbrkt > 0 && str.charAt(descend) == "[" && str.charAt(urlend-1) == "]") {
+ descend--;
+ urlend--;
+ result.newwin = true;
+ }
+ }
+
+ else if (str.charAt(urlend)=="}") { // page and workspace form
+ descend = lastbrace - 1;
+ pageform = true;
+ wsend = lastbrkt;
+ urlend--;
+ if (lastbrkt > 0 && str.charAt(lastbrkt-1) == "[" && str.charAt(urlend-1) == "]") {
+ wsend = lastbrkt-1;
+ urlend--;
+ result.newwin = true;
+ }
+ if (str.charAt(wsend-1)==" ") { // trim trailing space in workspace name
+ wsend--;
+ }
+ result.workspace = str.substring(lastbrace+1, wsend) || "";
+ }
+
+ if (str.charAt(descend)==" ") { // trim trailing space on desc
+ descend--;
+ }
+
+ if (str.charAt(descstart) == '"' && str.charAt(descend) == '"') {
+ descstart++;
+ descend--;
+ }
+ }
+
+ if (pageform) {
+ result.pagename = str.substring(lastbrkt+1, urlend) || "";
+ }
+ else {
+ result.url = str.substring(lastlt+1, urlend) || "";
+ }
+
+ if (descend >= descstart) {
+ result.desc = str.substring(descstart, descend+1);
+ }
+
+ return result;
+
+ }
+
+
+//
+// result = SocialCalc.ConvertSaveToOtherFormat(savestr, outputformat, dorecalc)
+//
+// Returns a string in the specificed format: "scsave", "html", "csv", "tab" (tab delimited)
+// If dorecalc is true, performs a recalc after loading (NO: obsolete!).
+//
+
+SocialCalc.ConvertSaveToOtherFormat = function(savestr, outputformat, dorecalc) {
+
+ var sheet, context, clipextents, div, ele, row, col, cr, cell, str;
+
+ var result = "";
+
+ if (outputformat == "scsave") {
+ return savestr;
+ }
+
+ if (savestr == "") {
+ return "";
+ }
+
+ sheet = new SocialCalc.Sheet();
+ sheet.ParseSheetSave(savestr);
+
+ if (dorecalc) {
+ // no longer supported as of 9/10/08
+ // Recalc is now async, so can't do it this way
+ throw("SocialCalc.ConvertSaveToOtherFormat: Not doing recalc.");
+ }
+
+ if (sheet.copiedfrom) {
+ clipextents = SocialCalc.ParseRange(sheet.copiedfrom);
+ }
+ else {
+ clipextents = {cr1: {row: 1, col: 1}, cr2: {row: sheet.attribs.lastrow, col: sheet.attribs.lastcol}};
+ }
+
+ if (outputformat == "html") {
+ context=new SocialCalc.RenderContext(sheet);
+ if (sheet.copiedfrom) {
+ context.rowpanes[0] = {first: clipextents.cr1.row, last: clipextents.cr2.row};
+ context.colpanes[0] = {first: clipextents.cr1.col, last: clipextents.cr2.col};
+ }
+ div = document.createElement("div");
+ ele = context.RenderSheet(null, context.defaultHTMLlinkstyle);
+ div.appendChild(ele);
+ delete context;
+ delete sheet;
+ result = div.innerHTML;
+ delete ele;
+ delete div;
+ return result;
+ }
+
+ for (row = clipextents.cr1.row; row <= clipextents.cr2.row; row++) {
+ for (col = clipextents.cr1.col; col <= clipextents.cr2.col; col++) {
+ cr = SocialCalc.crToCoord(col, row);
+ cell = sheet.GetAssuredCell(cr);
+
+ if (cell.errors) {
+ str = cell.errors;
+ }
+ else {
+ str = cell.datavalue+""; // get value as text
+ }
+
+ if (outputformat == "csv") {
+ if (str.indexOf('"')!=-1) {
+ str = str.replace(/"/g, '""'); // double quotes
+ }
+ if (/[, \n"]/.test(str)) {
+ str = '"' + str + '"'; // add quotes
+ }
+ if (col>clipextents.cr1.col) {
+ str = "," + str; // add commas
+ }
+ }
+ else if (outputformat == "tab") {
+ if (str.indexOf('\n')!=-1) { // if multiple lines
+ if (str.indexOf('"')!=-1) {
+ str = str.replace(/"/g, '""'); // double quotes
+ }
+ str = '"' + str + '"'; // add quotes
+ }
+ if (col>clipextents.cr1.col) {
+ str = "\t" + str; // add tabs
+ }
+ }
+ result += str;
+ }
+ result += "\n";
+ }
+
+ return result;
+
+ }
+
+
+//
+// result = SocialCalc.ConvertOtherFormatToSave(inputstr, inputformat)
+//
+// Returns a string converted from the specified format: "scsave", "csv", "tab" (tab delimited)
+//
+
+SocialCalc.ConvertOtherFormatToSave = function(inputstr, inputformat) {
+
+ var sheet, context, lines, i, line, value, inquote, j, ch, values, row, col, cr, maxc;
+
+ var result = "";
+
+ var AddCell = function() {
+ col++;
+ if (col>maxc) maxc = col;
+ cr = SocialCalc.crToCoord(col, row);
+ SocialCalc.SetConvertedCell(sheet, cr, value);
+ value = "";
+ }
+
+ if (inputformat == "scsave") {
+ return inputstr;
+ }
+
+ sheet = new SocialCalc.Sheet();
+
+ lines = inputstr.split(/\r\n|\n/);
+
+ maxc = 0;
+ if (inputformat == "csv") {
+ row = 0;
+ inquote = false;
+ for (i=0; i<lines.length; i++) {
+ if (i==lines.length-1 && lines[i]=="") { // extra null line - ignore
+ break;
+ }
+ if (inquote) { // if inquote, just continue from where left off
+ value += "\n";
+ }
+ else { // otherwise next row
+ value = "";
+ row++;
+ col = 0;
+ }
+ line = lines[i];
+ for (j=0; j<line.length; j++) {
+ ch = line.charAt(j);
+ if (ch == '"') {
+ if (inquote) {
+ if (j<line.length-1 && line.charAt(j+1) == '"') { // double quotes
+ j++; // skip the second one
+ value += '"'; // add one quote
+ }
+ else {
+ inquote = false;
+ if (j==line.length-1) { // at end of line
+ AddCell();
+ }
+ }
+ }
+ else {
+ inquote = true;
+ }
+ continue;
+ }
+ if (ch == "," && !inquote) {
+ AddCell();
+ }
+ else {
+ value += ch;
+ }
+ if (j==line.length-1 && !inquote) {
+ AddCell();
+ }
+ }
+ }
+ if (maxc>0) {
+ sheet.attribs.lastrow = row;
+ sheet.attribs.lastcol = maxc;
+ result = sheet.CreateSheetSave("A1:"+SocialCalc.crToCoord(maxc, row));
+ }
+ }
+
+ if (inputformat == "tab") {
+ row = 0;
+ inquote = false;
+ for (i=0; i<lines.length; i++) {
+ if (i==lines.length-1 && lines[i]=="") { // extra null line - ignore
+ break;
+ }
+ if (inquote) { // if inquote, just continue from where left off
+ value += "\n";
+ }
+ else { // otherwise next row
+ value = "";
+ row++;
+ col = 0;
+ }
+ line = lines[i];
+ for (j=0; j<line.length; j++) {
+ ch = line.charAt(j);
+ if (ch == '"') {
+ if (inquote) {
+ if (j<line.length-1) {
+ if (line.charAt(j+1) == '"') { // double quotes
+ j++; // skip the second one
+ value += '"'; // add one quote
+ }
+ else if (line.charAt(j+1) == '\t') { // end of quoted item
+ j++;
+ inquote = false;
+ AddCell();
+ }
+ }
+ else { // at end of line
+ inquote = false;
+ AddCell();
+ }
+ continue;
+ }
+ if (value=="") { // quote at start of item
+ inquote = true;
+ continue;
+ }
+ }
+ if (ch == "\t" && !inquote) {
+ AddCell();
+ }
+ else {
+ value += ch;
+ }
+ if (j==line.length-1 && !inquote) {
+ AddCell();
+ }
+ }
+ }
+ if (maxc>0) {
+ sheet.attribs.lastrow = row;
+ sheet.attribs.lastcol = maxc;
+ result = sheet.CreateSheetSave("A1:"+SocialCalc.crToCoord(maxc, row));
+ }
+ }
+
+ return result;
+
+ }
+
+//
+// SocialCalc.SetConvertedCell(sheet, cr, rawvalue)
+//
+// Sets the cell cr with a value and type determined from rawvalue
+//
+
+SocialCalc.SetConvertedCell = function(sheet, cr, rawvalue) {
+
+ var cell, value;
+
+ cell = sheet.GetAssuredCell(cr);
+
+ value = SocialCalc.DetermineValueType(rawvalue);
+
+ if (value.type == 'n' && value.value == rawvalue) { // check that we don't need "constant" to remember original value
+ cell.datatype = "v";
+ cell.valuetype = "n";
+ cell.datavalue = value.value;
+ }
+ else if (value.type.charAt(0) == 't') { // text of some sort but left unchanged
+ cell.datatype = "t";
+ cell.valuetype = value.type;
+ cell.datavalue = value.value;
+ }
+ else { // special number types
+ cell.datatype = "c";
+ cell.valuetype = value.type;
+ cell.datavalue = value.value;
+ cell.formula = rawvalue;
+ }
+
+ }
+
diff --git a/web/socialcalcconstants.js b/web/socialcalcconstants.js
new file mode 100644
index 0000000..2f6152a
--- /dev/null
+++ b/web/socialcalcconstants.js
@@ -0,0 +1,792 @@
+//
+/*
+// The module of the SocialCalc package with customizable constants, strings, etc.
+// This is where most of the common localizations are done.
+//
+// (c) Copyright 2008, 2009 Socialtext, Inc.
+// All Rights Reserved.
+//
+// The contents of this file are subject to the Artistic License 2.0; you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at http://socialcalc.org/licenses/al-20/.
+//
+// Some of the other files in the SocialCalc package are licensed under
+// different licenses. Please note the licenses of the modules you use.
+//
+// Code History:
+//
+// Initially coded by Dan Bricklin of Software Garden, Inc., for Socialtext, Inc.
+// Based in part on the SocialCalc 1.1.0 code written in Perl.
+// The SocialCalc 1.1.0 code was:
+// Portions (c) Copyright 2005, 2006, 2007 Software Garden, Inc.
+// All Rights Reserved.
+// Portions (c) Copyright 2007 Socialtext, Inc.
+// All Rights Reserved.
+// The Perl SocialCalc started as modifications to the wikiCalc(R) program, version 1.0.
+// wikiCalc 1.0 was written by Software Garden, Inc.
+// Unless otherwise specified, referring to "SocialCalc" in comments refers to this
+// JavaScript version of the code, not the SocialCalc Perl code.
+//
+*/
+
+var SocialCalc;
+if (!SocialCalc) SocialCalc = {};
+
+// *************************************
+//
+// TO LEARN HOW TO LOCALIZE OR CUSTOMIZE SOCIALCALC, PLEASE READ THIS:
+//
+// The constants are all properties of the SocialCalc.Constants object.
+// They are grouped here by what they are for, which module uses them, etc.
+//
+// Properties whose names start with "s_" are strings, or arrays of strings,
+// that are good candidates for translation from the English.
+//
+// Other properties relate to visual settings, localization parameters, etc.
+//
+// These values are not used when SocialCalc modules are first loaded.
+// They may be modified before the first use of the routines that use them,
+// e.g., before creating SocialCalc objects.
+//
+// The exceptions are:
+// TooltipOffsetX and TooltipOffsetY, as described with their definitions.
+//
+// SocialCalc IS NOT DESIGNED FOR USE WITH A TRANSLATION FUNCTION each time a string
+// is used. Instead, language translations may be done by modifying this object.
+//
+// To customize SocialCalc, you may either replace this file with a modified version
+// or you can overwrite the values before use. An example would be to
+// iterate over all the properties looking for names that start with "s_" and
+// use some other mechanism to obtain a localized string and replace the values
+// here with those translated values.
+//
+// There is also a function, SocialCalc.ConstantsSetClasses, that may be used
+// to easily switch SocialCalc from using explicit CSS styles for many things
+// to using CSS classes. See the function, below, for more information.
+//
+// *************************************
+
+SocialCalc.Constants = {
+
+//
+// Main SocialCalc module, socialcalc-3.js:
+//
+
+ //*** Common Constants
+
+ textdatadefaulttype: "t", // This sets the default type for text on reading source file
+ // It should normally be "t"
+
+ //*** Common error messages
+
+ s_BrowserNotSupported: "Browser not supported.", // error thrown if browser can't handle events like IE or Firefox.
+ s_InternalError: "Internal SocialCalc error (probably an internal bug): ", // hopefully unlikely, but a test failed
+
+ //*** SocialCalc.ParseSheetSave
+
+ // Errors thrown on unexpected value in save file:
+
+ s_pssUnknownColType: "Unknown col type item",
+ s_pssUnknownRowType: "Unknown row type item",
+ s_pssUnknownLineType: "Unknown line type",
+
+ //*** SocialCalc.CellFromStringParts
+
+ // Error thrown on unexpected value in save file:
+
+ s_cfspUnknownCellType: "Unknown cell type item",
+
+ //*** SocialCalc.CanonicalizeSheet
+
+ doCanonicalizeSheet: true, // if true, do the canonicalization calculations
+
+ //*** ExecuteSheetCommand
+
+ s_escUnknownSheetCmd: "Unknown sheet command: ",
+ s_escUnknownSetCoordCmd: "Unknown set coord command: ",
+ s_escUnknownCmd: "Unknown command: ",
+
+ //*** SocialCalc.CheckAndCalcCell
+
+ s_caccCircRef: "Circular reference to ", // circular reference found during recalc
+
+ //*** SocialCalc.RenderContext
+
+ defaultRowNameWidth: "30", // used to set minimum width of the row header column - a string in pixels
+ defaultAssumedRowHeight: 15, // used when guessing row heights - number
+ defaultCellIDPrefix: "cell_", // if non-null, each cell will render with an ID starting with this
+
+ // Default sheet display values
+
+ defaultCellLayout: "padding:2px 2px 1px 2px;vertical-align:top;",
+ defaultCellFontStyle: "normal normal",
+ defaultCellFontSize: "small",
+ defaultCellFontFamily: "Verdana,Arial,Helvetica,sans-serif",
+
+ defaultPaneDividerWidth: "2", // a string
+ defaultPaneDividerHeight: "3", // a string
+
+ defaultGridCSS: "1px solid #C0C0C0;", // used as style to set each border when grid enabled (was #ECECEC)
+
+ defaultCommentClass: "", // class added to cells with non-null comments when grid enabled
+ defaultCommentStyle: "background-repeat:no-repeat;background-position:top right;background-image:url(images/sc-commentbg.gif);", // style added to cells with non-null comments when grid enabled
+ defaultCommentNoGridClass: "", // class added to cells with non-null comments when grid not enabled
+ defaultCommentNoGridStyle: "", // style added to cells with non-null comments when grid not enabled
+
+ defaultColWidth: "80", // text
+ defaultMinimumColWidth: 10, // numeric
+
+ // For each of the following default sheet display values at least one of class and/or style are needed
+
+ defaultHighlightTypeCursorClass: "",
+ defaultHighlightTypeCursorStyle: "color:#FFF;backgroundColor:#A6A6A6;",
+ defaultHighlightTypeRangeClass: "",
+ defaultHighlightTypeRangeStyle: "color:#000;backgroundColor:#E5E5E5;",
+
+ defaultColnameClass: "", // regular column heading letters, needs a cursor property
+ defaultColnameStyle: "font-size:small;text-align:center;color:#FFFFFF;background-color:#808080;cursor:e-resize;",
+ defaultSelectedColnameClass: "", // column with selected cell, needs a cursor property
+ defaultSelectedColnameStyle: "font-size:small;text-align:center;color:#FFFFFF;background-color:#404040;cursor:e-resize;",
+ defaultRownameClass: "", // regular row heading numbers
+ defaultRownameStyle: "font-size:small;text-align:right;color:#FFFFFF;background-color:#808080;",
+ defaultSelectedRownameClass: "", // column with selected cell, needs a cursor property
+ defaultSelectedRownameStyle: "font-size:small;text-align:right;color:#FFFFFF;background-color:#404040;",
+ defaultUpperLeftClass: "", // Corner cell in upper left
+ defaultUpperLeftStyle: "font-size:small;",
+ defaultSkippedCellClass: "", // used if present for spanned cells peeking into a pane (at least one of class/style needed)
+ defaultSkippedCellStyle: "font-size:small;background-color:#CCC", // used if present
+ defaultPaneDividerClass: "", // used if present for the look of the space between panes (at least one of class/style needed)
+ defaultPaneDividerStyle: "font-size:small;background-color:#C0C0C0;padding:0px;", // used if present
+
+ s_rcMissingSheet: "Render Context must have a sheet object", // unlikely thrown error
+
+ //*** SocialCalc.format_text_for_display
+
+ defaultLinkFormatString: '<span style="font-size:smaller;text-decoration:none !important;background-color:#66B;color:#FFF;">Link</span>', // used for format "text-link"; you could make this an img tag if desired
+// defaultLinkFormatString: '<img src="images/sc-linkout.gif" border="0" alt="Link out" title="Link out">',
+ defaultPageLinkFormatString: '<span style="font-size:smaller;text-decoration:none !important;background-color:#66B;color:#FFF;">Page</span>', // used for format "text-link"; you could make this an img tag if desired
+
+ //*** SocialCalc.format_number_for_display
+
+ defaultFormatdt: 'd-mmm-yyyy h:mm:ss',
+ defaultFormatd: 'd-mmm-yyyy',
+ defaultFormatt: '[h]:mm:ss',
+ defaultDisplayTRUE: 'TRUE', // how TRUE shows when rendered
+ defaultDisplayFALSE: 'FALSE',
+
+//
+// SocialCalc Table Editor module, socialcalctableeditor.js:
+//
+
+ //*** SocialCalc.TableEditor
+
+ defaultImagePrefix: "images/sc-", // URL prefix for images (e.g., "/images/sc")
+ defaultTableEditorIDPrefix: "te_", // if present, many TableEditor elements are assigned IDs with this prefix
+ defaultPageUpDnAmount: 15, // number of rows to move cursor on PgUp/PgDn keys (numeric)
+
+ AllowCtrlS: true, // turns on Ctrl-S trapdoor for setting custom numeric formats and commands if true
+
+ //*** SocialCalc.CreateTableEditor
+
+ defaultTableControlThickness: 20, // the short size for the scrollbars, etc. (numeric in pixels)
+ cteGriddivClass: "", // if present, the class for the TableEditor griddiv element
+
+ //** SocialCalc.EditorGetStatuslineString -- strings shown on status line
+
+ s_statusline_executing: "Executing...",
+ s_statusline_displaying: "Displaying...",
+ s_statusline_ordering: "Ordering...",
+ s_statusline_calculating: "Calculating...",
+ s_statusline_calculatingls: "Calculating... Loading Sheet...",
+ s_statusline_doingserverfunc: "doing server function ",
+ s_statusline_incell: " in cell ",
+ s_statusline_calcstart: "Calculation start...",
+ s_statusline_sum: "SUM",
+ s_statusline_recalcneeded: '<span style="color:#999;">(Recalc needed)</span>',
+ s_statusline_circref: '<span style="color:red;">Circular reference: ',
+
+ //** SocialCalc.InputBoxDisplayCellContents
+
+ s_inputboxdisplaymultilinetext: "[Multi-line text: Click icon on right to edit]",
+
+ //** SocialCalc.InputEcho
+
+ defaultInputEchoClass: "", // if present, the class of the popup inputEcho div
+ defaultInputEchoStyle: "filter:alpha(opacity=90);opacity:.9;backgroundColor:#FFD;border:1px solid #884;"+
+ "fontSize:small;padding:2px 10px 1px 2px;cursor:default;", // if present, pseudo style
+ defaultInputEchoPromptClass: "", // if present, the class of the popup inputEcho div
+ defaultInputEchoPromptStyle: "filter:alpha(opacity=90);opacity:.9;backgroundColor:#FFD;"+
+ "borderLeft:1px solid #884;borderRight:1px solid #884;borderBottom:1px solid #884;"+
+ "fontSize:small;fontStyle:italic;padding:2px 10px 1px 2px;cursor:default;", // if present, pseudo style
+
+ //** SocialCalc.InputEchoText
+
+ ietUnknownFunction: "Unknown function ", // displayed when typing "=unknown("
+
+ //*** SocialCalc.TableControl
+
+ defaultTCSliderThickness: 9, // length of pane slider (numeric in pixels)
+ defaultTCButtonThickness: 20, // length of scroll +/- buttons (numeric in pixels)
+ defaultTCThumbThickness: 15, // length of thumb (numeric in pixels)
+
+ //*** SocialCalc.CreateTableControl
+
+ TCmainStyle: "backgroundColor:#EEE;", // if present, pseudo style (text-align is textAlign) for main div of a table control
+ TCmainClass: "", // if present, the CSS class of the main div for a table control
+ TCendcapStyle: "backgroundColor:#FFF;", // backgroundColor may be used while waiting for image that may not come
+ TCendcapClass: "",
+ TCpanesliderStyle: "backgroundColor:#CCC;",
+ TCpanesliderClass: "",
+ s_panesliderTooltiph: "Drag to lock pane vertically", // tooltip for horizontal table control pane slider
+ s_panesliderTooltipv: "Drag to lock pane horizontally",
+ TClessbuttonStyle: "backgroundColor:#AAA;",
+ TClessbuttonClass: "",
+ TClessbuttonRepeatWait: 500, // in milliseconds
+ TClessbuttonRepeatInterval: 100, // in milliseconds
+ TCmorebuttonStyle: "backgroundColor:#AAA;",
+ TCmorebuttonClass: "",
+ TCmorebuttonRepeatWait: 500, // in milliseconds
+ TCmorebuttonRepeatInterval: 100, // in milliseconds
+ TCscrollareaStyle: "backgroundColor:#DDD;",
+ TCscrollareaClass: "",
+ TCscrollareaRepeatWait: 500, // in milliseconds
+ TCscrollareaRepeatInterval: 100, // in milliseconds
+ TCthumbClass: "",
+ TCthumbStyle: "backgroundColor:#CCC;",
+
+ //*** SocialCalc.TCPSDragFunctionStart
+
+ TCPStrackinglineClass: "", // at least one of class/style for pane slider tracking line display in table control
+ TCPStrackinglineStyle: "overflow:hidden;position:absolute;zIndex:100;",
+ // if present, pseudo style (text-align is textAlign)
+ TCPStrackinglineThickness: "2px", // narrow dimension of trackling line (string with units)
+
+
+ //*** SocialCalc.TCTDragFunctionStart
+
+ TCTDFSthumbstatusvClass: "", // at least one of class/style for vertical thumb dragging status display in table control
+ TCTDFSthumbstatusvStyle: "height:20px;width:auto;border:3px solid #808080;overflow:hidden;"+
+ "backgroundColor:#FFF;fontSize:small;position:absolute;zIndex:100;",
+ // if present, pseudo style (text-align is textAlign)
+ TCTDFSthumbstatushClass: "", // at least one of class/style for horizontal thumb dragging status display in table control
+ TCTDFSthumbstatushStyle: "height:20px;width:auto;border:1px solid black;padding:2px;"+
+ "backgroundColor:#FFF;fontSize:small;position:absolute;zIndex:100;",
+ // if present, pseudo style (text-align is textAlign)
+ TCTDFSthumbstatusrownumClass: "", // at least one of class/style for thumb dragging status display in table control
+ TCTDFSthumbstatusrownumStyle: "color:#FFF;background-color:#808080;font-size:small;white-space:nowrap;padding:3px;", // if present, real style
+ TCTDFStopOffsetv: 0, // offsets for thumbstatus display while dragging
+ TCTDFSleftOffsetv: -80,
+ s_TCTDFthumbstatusPrefixv: "Row ", // Text Control Drag Function text before row number
+ TCTDFStopOffseth: -30,
+ TCTDFSleftOffseth: 0,
+ s_TCTDFthumbstatusPrefixh: "Col ", // Text Control Drag Function text before col number
+
+ //*** SocialCalc.TooltipInfo
+
+ // Note: These two values are used to set the TooltipInfo initial values when the code is first read in.
+ // Modifying them here after loading has no effect -- you need to modify SocialCalc.TooltipInfo directly
+ // to dynamically set them. This is different than most other constants which may be modified until use.
+
+ TooltipOffsetX: 2, // offset in pixels from mouse position (to right on left side of screen, to left on right)
+ TooltipOffsetY: 10, // offset in pixels above mouse position for lower edge
+
+ //*** SocialCalc.TooltipDisplay
+
+ TDpopupElementClass: "", // at least one of class/style for tooltip display
+ TDpopupElementStyle: "border:1px solid black;padding:1px 2px 2px 2px;textAlign:center;backgroundColor:#FFF;"+
+ "fontSize:7pt;fontFamily:Verdana,Arial,Helvetica,sans-serif;"+
+ "position:absolute;width:auto;zIndex:110;",
+ // if present, pseudo style (text-align is textAlign)
+
+
+//
+// SocialCalc Spreadsheet Control module, socialcalcspreadsheetcontrol.js:
+//
+
+ //*** SocialCalc.SpreadsheetControl
+
+ SCToolbarbackground: "background-color:#404040;min-height:80px;",
+ SCTabbackground: "background-color:#CCC;",
+ SCTabselectedCSS: "font-size:small;padding:6px 30px 6px 8px;color:#FFF;background-color:#404040;cursor:default;border-right:1px solid #CCC;",
+ SCTabplainCSS: "font-size:small;padding:6px 30px 6px 8px;color:#FFF;background-color:#808080;cursor:default;border-right:1px solid #CCC;",
+ SCToolbartext: "font-size:x-small;font-weight:bold;color:#FFF;padding-bottom:4px;",
+
+ SCFormulabarheight: 50, // in pixels, will contain a text input box
+
+ SCStatuslineheight: 30, // in pixels
+ SCStatuslineCSS: "font-size:10px;padding:3px 0px;",
+
+ // Constants for default Format tab (settings)
+ //
+ // *** EVEN THOUGH THESE DON'T START WITH s_: ***
+ //
+ // These should be carefully checked for localization. Make sure you understand what they do and how they work!
+ // The first part of "first:second|first:second|..." is what is displayed and the second is the value to be used.
+ // The value is normally not translated -- only the displayed part. The [cancel], [break], etc., are not translated --
+ // they are commands to SocialCalc.SettingsControls.PopupListInitialize
+
+ SCFormatNumberFormats: "[cancel]:|[break]:|%loc!Default!:|[custom]:|%loc!Automatic!:general|%loc!Auto w/ commas!:[,]General|[break]:|"+
+ "00:00|000:000|0000:0000|00000:00000|[break]:|%loc!Formula!:formula|%loc!Hidden!:hidden|[newcol]:"+
+ "1234:0|1,234:#,##0|1,234.5:#,##0.0|1,234.56:#,##0.00|1,234.567:#,##0.000|1,234.5678:#,##0.0000|"+
+ "[break]:|1,234%:#,##0%|1,234.5%:#,##0.0%|1,234.56%:#,##0.00%|"+
+ "[newcol]:|$1,234:$#,##0|$1,234.5:$#,##0.0|$1,234.56:$#,##0.00|[break]:|"+
+ "(1,234):#,##0_);(#,##0)|(1,234.5):#,##0.0_);(#,##0.0)|(1,234.56):#,##0.00_);(#,##0.00)|[break]:|"+
+ "($1,234):#,##0_);($#,##0)|($1,234.5):$#,##0.0_);($#,##0.0)|($1,234.56):$#,##0.00_);($#,##0.00)|"+
+ "[newcol]:|1/4/06:m/d/yy|01/04/2006:mm/dd/yyyy|2006-01-04:yyyy-mm-dd|4-Jan-06:d-mmm-yy|04-Jan-2006:dd-mmm-yyyy|January 4, 2006:mmmm d, yyyy|"+
+ "[break]:|1\\c23:h:mm|1\\c23 PM:h:mm AM/PM|1\\c23\\c45:h:mm:ss|01\\c23\\c45:hh:mm:ss|26\\c23 (h\\cm):[hh]:mm|69\\c45 (m\\cs):[mm]:ss|69 (s):[ss]|"+
+ "[newcol]:|2006-01-04 01\\c23\\c45:yyyy-mm-dd hh:mm:ss|January 4, 2006:mmmm d, yyyy hh:mm:ss|Wed:ddd|Wednesday:dddd|",
+ SCFormatTextFormats: "[cancel]:|[break]:|%loc!Default!:|[custom]:|%loc!Automatic!:general|%loc!Plain Text!:text-plain|"+
+ "HTML:text-html|%loc!Link!:text-link|%loc!Formula!:formula|%loc!Hidden!:hidden|",
+ SCFormatPadsizes: "[cancel]:|[break]:|%loc!Default!:|[custom]:|%loc!No padding!:0px|"+
+ "[newcol]:|1 pixel:1px|2 pixels:2px|3 pixels:3px|4 pixels:4px|5 pixels:5px|"+
+ "6 pixels:6px|7 pixels:7px|8 pixels:8px|[newcol]:|9 pixels:9px|10 pixels:10px|11 pixels:11px|"+
+ "12 pixels:12px|13 pixels:13px|14 pixels:14px|16 pixels:16px|"+
+ "18 pixels:18px|[newcol]:|20 pixels:20px|22 pixels:22px|24 pixels:24px|28 pixels:28px|36 pixels:36px|",
+ SCFormatFontsizes: "[cancel]:|[break]:|%loc!Default!:|[custom]:|X-Small:x-small|Small:small|Medium:medium|Large:large|X-Large:x-large|"+
+ "[newcol]:|6pt:6pt|7pt:7pt|8pt:8pt|9pt:9pt|10pt:10pt|11pt:11pt|12pt:12pt|14pt:14pt|16pt:16pt|"+
+ "[newcol]:|18pt:18pt|20pt:20pt|22pt:22pt|24pt:24pt|28pt:28pt|36pt:36pt|48pt:48pt|72pt:72pt|"+
+ "[newcol]:|8 pixels:8px|9 pixels:9px|10 pixels:10px|11 pixels:11px|"+
+ "12 pixels:12px|13 pixels:13px|14 pixels:14px|[newcol]:|16 pixels:16px|"+
+ "18 pixels:18px|20 pixels:20px|22 pixels:22px|24 pixels:24px|28 pixels:28px|36 pixels:36px|",
+ SCFormatFontfamilies: "[cancel]:|[break]:|%loc!Default!:|[custom]:|Verdana:Verdana,Arial,Helvetica,sans-serif|"+
+ "Arial:arial,helvetica,sans-serif|Courier:'Courier New',Courier,monospace|",
+ SCFormatFontlook: "[cancel]:|[break]:|%loc!Default!:|%loc!Normal!:normal normal|%loc!Bold!:normal bold|%loc!Italic!:italic normal|"+
+ "%loc!Bold Italic!:italic bold",
+ SCFormatTextAlignhoriz: "[cancel]:|[break]:|%loc!Default!:|%loc!Left!:left|%loc!Center!:center|%loc!Right!:right|",
+ SCFormatNumberAlignhoriz: "[cancel]:|[break]:|%loc!Default!:|%loc!Left!:left|%loc!Center!:center|%loc!Right!:right|",
+ SCFormatAlignVertical: "[cancel]:|[break]:|%loc!Default!:|%loc!Top!:top|%loc!Middle!:middle|%loc!Bottom!:bottom|",
+ SCFormatColwidth: "[cancel]:|[break]:|%loc!Default!:|[custom]:|[newcol]:|"+
+ "20 pixels:20|40:40|60:60|80:80|100:100|120:120|140:140|160:160|"+
+ "[newcol]:|180 pixels:180|200:200|220:220|240:240|260:260|280:280|300:300|",
+ SCFormatRecalc: "[cancel]:|[break]:|%loc!Auto!:|%loc!Manual!:off|",
+
+ //*** SocialCalc.InitializeSpreadsheetControl
+
+ ISCButtonBorderNormal: "#404040",
+ ISCButtonBorderHover: "#999",
+ ISCButtonBorderDown: "#FFF",
+ ISCButtonDownBackground: "#888",
+
+ //*** SocialCalc.SettingsControls.PopupListInitialize
+
+ s_PopupListCancel: "[Cancel]",
+ s_PopupListCustom: "Custom",
+
+ // ***
+ //
+ // s_loc_ constants accessed by SocialCalc.LocalizeString and SocialCalc.LocalizeSubstrings
+ //
+ // Used extensively by socialcalcspreadsheetcontrol.js
+ //
+ // ***
+
+ s_loc_align_center: "Align Center",
+ s_loc_align_left: "Align Left",
+ s_loc_align_right: "Align Right",
+ s_loc_alignment: "Alignment",
+ s_loc_audit: "Audit",
+ s_loc_audit_trail_this_session: "Audit Trail This Session",
+ s_loc_auto: "Auto",
+ s_loc_auto_sum: "Auto Sum",
+ s_loc_auto_wX_commas: "Auto w/ commas",
+ s_loc_automatic: "Automatic",
+ s_loc_background: "Background",
+ s_loc_bold: "Bold",
+ s_loc_bold_XampX_italics: "Bold &amp; Italics",
+ s_loc_bold_italic: "Bold Italic",
+ s_loc_borders: "Borders",
+ s_loc_borders_off: "Borders Off",
+ s_loc_borders_on: "Borders On",
+ s_loc_bottom: "Bottom",
+ s_loc_bottom_border: "Bottom Border",
+ s_loc_cell_settings: "CELL SETTINGS",
+ s_loc_csv_format: "CSV format",
+ s_loc_cancel: "Cancel",
+ s_loc_category: "Category",
+ s_loc_center: "Center",
+ s_loc_clear: "Clear",
+ s_loc_clear_socialcalc_clipboard: "Clear SocialCalc Clipboard",
+ s_loc_clipboard: "Clipboard",
+ s_loc_color: "Color",
+ s_loc_column_: "Column ",
+ s_loc_comment: "Comment",
+ s_loc_copy: "Copy",
+ s_loc_custom: "Custom",
+ s_loc_cut: "Cut",
+ s_loc_default: "Default",
+ s_loc_default_alignment: "Default Alignment",
+ s_loc_default_column_width: "Default Column Width",
+ s_loc_default_font: "Default Font",
+ s_loc_default_format: "Default Format",
+ s_loc_default_padding: "Default Padding",
+ s_loc_delete: "Delete",
+ s_loc_delete_column: "Delete Column",
+ s_loc_delete_contents: "Delete Contents",
+ s_loc_delete_row: "Delete Row",
+ s_loc_description: "Description",
+ s_loc_display_clipboard_in: "Display Clipboard in",
+ s_loc_down: "Down",
+ s_loc_edit: "Edit",
+ s_loc_existing_names: "Existing Names",
+ s_loc_family: "Family",
+ s_loc_fill_down: "Fill Down",
+ s_loc_fill_right: "Fill Right",
+ s_loc_font: "Font",
+ s_loc_format: "Format",
+ s_loc_formula: "Formula",
+ s_loc_function_list: "Function List",
+ s_loc_functions: "Functions",
+ s_loc_grid: "Grid",
+ s_loc_hidden: "Hidden",
+ s_loc_horizontal: "Horizontal",
+ s_loc_insert_column: "Insert Column",
+ s_loc_insert_row: "Insert Row",
+ s_loc_italic: "Italic",
+ s_loc_last_sort: "Last Sort",
+ s_loc_left: "Left",
+ s_loc_left_border: "Left Border",
+ s_loc_link: "Link",
+ s_loc_link_input_box: "Link Input Box",
+ s_loc_list: "List",
+ s_loc_load_socialcalc_clipboard_with_this: "Load SocialCalc Clipboard With This",
+ s_loc_major_sort: "Major Sort",
+ s_loc_manual: "Manual",
+ s_loc_merge_cells: "Merge Cells",
+ s_loc_middle: "Middle",
+ s_loc_minor_sort: "Minor Sort",
+ s_loc_move_insert: "Move Insert",
+ s_loc_move_paste: "Move Paste",
+ s_loc_multiXline_input_box: "Multi-line Input Box",
+ s_loc_name: "Name",
+ s_loc_names: "Names",
+ s_loc_no_padding: "No padding",
+ s_loc_normal: "Normal",
+ s_loc_number: "Number",
+ s_loc_number_horizontal: "Number Horizontal",
+ s_loc_ok: "OK",
+ s_loc_padding: "Padding",
+ s_loc_page_name: "Page Name",
+ s_loc_paste: "Paste",
+ s_loc_paste_formats: "Paste Formats",
+ s_loc_plain_text: "Plain Text",
+ s_loc_recalc: "Recalc",
+ s_loc_recalculation: "Recalculation",
+ s_loc_redo: "Redo",
+ s_loc_right: "Right",
+ s_loc_right_border: "Right Border",
+ s_loc_sheet_settings: "SHEET SETTINGS",
+ s_loc_save: "Save",
+ s_loc_save_to: "Save to",
+ s_loc_set_cell_contents: "Set Cell Contents",
+ s_loc_set_cells_to_sort: "Set Cells To Sort",
+ s_loc_set_value_to: "Set Value To",
+ s_loc_set_to_link_format: "Set to Link format",
+ s_loc_setXclear_move_from: "Set/Clear Move From",
+ s_loc_show_cell_settings: "Show Cell Settings",
+ s_loc_show_sheet_settings: "Show Sheet Settings",
+ s_loc_show_in_new_browser_window: "Show in new browser window",
+ s_loc_size: "Size",
+ s_loc_socialcalcXsave_format: "SocialCalc-save format",
+ s_loc_sort: "Sort",
+ s_loc_sort_: "Sort ",
+ s_loc_sort_cells: "Sort Cells",
+ s_loc_swap_colors: "Swap Colors",
+ s_loc_tabXdelimited_format: "Tab-delimited format",
+ s_loc_text: "Text",
+ s_loc_text_horizontal: "Text Horizontal",
+ s_loc_this_is_aXbrXsample: "This is a<br>sample",
+ s_loc_top: "Top",
+ s_loc_top_border: "Top Border",
+ s_loc_undone_steps: "UNDONE STEPS",
+ s_loc_url: "URL",
+ s_loc_undo: "Undo",
+ s_loc_unmerge_cells: "Unmerge Cells",
+ s_loc_up: "Up",
+ s_loc_value: "Value",
+ s_loc_vertical: "Vertical",
+ s_loc_workspace: "Workspace",
+ s_loc_XnewX: "[New]",
+ s_loc_XnoneX: "[None]",
+ s_loc_Xselect_rangeX: "[select range]",
+
+//
+// SocialCalc Format Number module, formatnumber2.js:
+//
+
+ FormatNumber_separatorchar: ",", // the thousands separator character when formatting numbers for display
+ FormatNumber_decimalchar: ".", // the decimal separator character when formatting numbers for display
+ FormatNumber_defaultCurrency: "$", // the currency string used if none specified
+
+ // The following constants are arrays of strings with the short (3 character) and full names of days and months
+
+ s_FormatNumber_daynames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
+ s_FormatNumber_daynames3: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
+ s_FormatNumber_monthnames: ["January", "February", "March", "April", "May", "June", "July", "August", "September",
+ "October", "November", "December"],
+ s_FormatNumber_monthnames3: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
+ s_FormatNumber_am: "AM",
+ s_FormatNumber_am1: "A",
+ s_FormatNumber_pm: "PM",
+ s_FormatNumber_pm1: "P",
+
+//
+// SocialCalc Spreadsheet Formula module, formula1.js:
+//
+
+ s_parseerrexponent: "Improperly formed number exponent",
+ s_parseerrchar: "Unexpected character in formula",
+ s_parseerrstring: "Improperly formed string",
+ s_parseerrspecialvalue: "Improperly formed special value",
+ s_parseerrtwoops: "Error in formula (two operators inappropriately in a row)",
+ s_parseerrmissingopenparen: "Missing open parenthesis in list with comma(s). ",
+ s_parseerrcloseparennoopen: "Closing parenthesis without open parenthesis. ",
+ s_parseerrmissingcloseparen: "Missing close parenthesis. ",
+ s_parseerrmissingoperand: "Missing operand. ",
+ s_parseerrerrorinformula: "Error in formula.",
+ s_calcerrerrorvalueinformula: "Error value in formula",
+ s_parseerrerrorinformulabadval: "Error in formula resulting in bad value",
+ s_formularangeresult: "Formula results in range value:",
+ s_calcerrnumericnan: "Formula results in an bad numeric value",
+ s_calcerrnumericoverflow: "Numeric overflow",
+ s_sheetunavailable: "Sheet unavailable:", // when FindSheetInCache returns null
+ s_calcerrcellrefmissing: "Cell reference missing when expected.",
+ s_calcerrsheetnamemissing: "Sheet name missing when expected.",
+ s_circularnameref: "Circular name reference to name",
+ s_calcerrunknownname: "Unknown name",
+ s_calcerrincorrectargstofunction: "Incorrect arguments to function",
+ s_sheetfuncunknownfunction: "Unknown function",
+ s_sheetfunclnarg: "LN argument must be greater than 0",
+ s_sheetfunclog10arg: "LOG10 argument must be greater than 0",
+ s_sheetfunclogsecondarg: "LOG second argument must be numeric greater than 0",
+ s_sheetfunclogfirstarg: "LOG first argument must be greater than 0",
+ s_sheetfuncroundsecondarg: "ROUND second argument must be numeric",
+ s_sheetfuncddblife: "DDB life must be greater than 1",
+ s_sheetfuncslnlife: "SLN life must be greater than 1",
+
+ // Function definition text
+
+ s_fdef_ABS: 'Absolute value function. ',
+ s_fdef_ACOS: 'Trigonometric arccosine function. ',
+ s_fdef_AND: 'True if all arguments are true. ',
+ s_fdef_ASIN: 'Trigonometric arcsine function. ',
+ s_fdef_ATAN: 'Trigonometric arctan function. ',
+ s_fdef_ATAN2: 'Trigonometric arc tangent function (result is in radians). ',
+ s_fdef_AVERAGE: 'Averages the values. ',
+ s_fdef_CHOOSE: 'Returns the value specified by the index. The values may be ranges of cells. ',
+ s_fdef_COLUMNS: 'Returns the number of columns in the range. ',
+ s_fdef_COS: 'Trigonometric cosine function (value is in radians). ',
+ s_fdef_COUNT: 'Counts the number of numeric values, not blank, text, or error. ',
+ s_fdef_COUNTA: 'Counts the number of non-blank values. ',
+ s_fdef_COUNTBLANK: "Counts the number of blank values. (Note: '' is not blank.) ",
+ s_fdef_COUNTIF: "Counts the number of number of cells in the range that meet the criteria. The criteria may be a value ('x', 15, 1+3) or a test (>25). ",
+ s_fdef_DATE: 'Returns the appropriate date value given numbers for year, month, and day. For example: DATE(2006,2,1) for February 1, 2006. Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. ',
+ s_fdef_DAVERAGE: 'Averages the values in the specified field in records that meet the criteria. ',
+ s_fdef_DAY: 'Returns the day of month for a date value. ',
+ s_fdef_DCOUNT: 'Counts the number of numeric values, not blank, text, or error, in the specified field in records that meet the criteria. ',
+ s_fdef_DCOUNTA: 'Counts the number of non-blank values in the specified field in records that meet the criteria. ',
+ s_fdef_DDB: 'Returns the amount of depreciation at the given period of time (the default factor is 2 for double-declining balance). ',
+ s_fdef_DEGREES: 'Converts value in radians into degrees. ',
+ s_fdef_DGET: 'Returns the value of the specified field in the single record that meets the criteria. ',
+ s_fdef_DMAX: 'Returns the maximum of the numeric values in the specified field in records that meet the criteria. ',
+ s_fdef_DMIN: 'Returns the maximum of the numeric values in the specified field in records that meet the criteria. ',
+ s_fdef_DPRODUCT: 'Returns the result of multiplying the numeric values in the specified field in records that meet the criteria. ',
+ s_fdef_DSTDEV: 'Returns the sample standard deviation of the numeric values in the specified field in records that meet the criteria. ',
+ s_fdef_DSTDEVP: 'Returns the standard deviation of the numeric values in the specified field in records that meet the criteria. ',
+ s_fdef_DSUM: 'Returns the sum of the numeric values in the specified field in records that meet the criteria. ',
+ s_fdef_DVAR: 'Returns the sample variance of the numeric values in the specified field in records that meet the criteria. ',
+ s_fdef_DVARP: 'Returns the variance of the numeric values in the specified field in records that meet the criteria. ',
+ s_fdef_EVEN: 'Rounds the value up in magnitude to the nearest even integer. ',
+ s_fdef_EXACT: 'Returns true if the values are exactly the same, including case, type, etc. ',
+ s_fdef_EXP: 'Returns e raised to the value power. ',
+ s_fdef_FACT: 'Returns factorial of the value. ',
+ s_fdef_FALSE: 'Returns the logical value false. ',
+ s_fdef_FIND: 'Returns the starting position within string2 of the first occurrence of string1 at or after start. If start is omitted, 1 is assumed. ',
+ s_fdef_FV: 'Returns the future value of repeated payments of money invested at the given rate for the specified number of periods, with optional present value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). ',
+ s_fdef_HLOOKUP: 'Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the row offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. ',
+ s_fdef_HOUR: 'Returns the hour portion of a time or date/time value. ',
+ s_fdef_IF: 'Results in true-value if logical-expression is TRUE or non-zero, otherwise results in false-value. ',
+ s_fdef_INDEX: 'Returns a cell or range reference for the specified row and column in the range. If range is 1-dimensional, then only one of rownum or colnum are needed. If range is 2-dimensional and rownum or colnum are zero, a reference to the range of just the specified column or row is returned. You can use the returned reference value in a range, e.g., sum(A1:INDEX(A2:A10,4)). ',
+ s_fdef_INT: 'Returns the value rounded down to the nearest integer (towards -infinity). ',
+ s_fdef_IRR: 'Returns the interest rate at which the cash flows in the range have a net present value of zero. Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). ',
+ s_fdef_ISBLANK: 'Returns true if the value is a reference to a blank cell. ',
+ s_fdef_ISERR: 'Returns true if the value is of type Error but not NA. ',
+ s_fdef_ISERROR: 'Returns true if the value is of type Error. ',
+ s_fdef_ISLOGICAL: 'Returns true if the value is of type Logical (true/false). ',
+ s_fdef_ISNA: 'Returns true if the value is the error type NA. ',
+ s_fdef_ISNONTEXT: 'Returns true if the value is not of type Text. ',
+ s_fdef_ISNUMBER: 'Returns true if the value is of type Number (including logical values). ',
+ s_fdef_ISTEXT: 'Returns true if the value is of type Text. ',
+ s_fdef_LEFT: 'Returns the specified number of characters from the text value. If count is omitted, 1 is assumed. ',
+ s_fdef_LEN: 'Returns the number of characters in the text value. ',
+ s_fdef_LN: 'Returns the natural logarithm of the value. ',
+ s_fdef_LOG: 'Returns the logarithm of the value using the specified base. ',
+ s_fdef_LOG10: 'Returns the base 10 logarithm of the value. ',
+ s_fdef_LOWER: 'Returns the text value with all uppercase characters converted to lowercase. ',
+ s_fdef_MATCH: 'Look for the matching value for the given value in the range and return position (the first is 1) in that range. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match<=value) instead of exact match. If rangelookup is -1, act like 1 but the bracket is match>=value. ',
+ s_fdef_MAX: 'Returns the maximum of the numeric values. ',
+ s_fdef_MID: 'Returns the specified number of characters from the text value starting from the specified position. ',
+ s_fdef_MIN: 'Returns the minimum of the numeric values. ',
+ s_fdef_MINUTE: 'Returns the minute portion of a time or date/time value. ',
+ s_fdef_MOD: 'Returns the remainder of the first value divided by the second. ',
+ s_fdef_MONTH: 'Returns the month part of a date value. ',
+ s_fdef_N: 'Returns the value if it is a numeric value otherwise an error. ',
+ s_fdef_NA: 'Returns the #N/A error value which propagates through most operations. ',
+ s_fdef_NOT: 'Returns FALSE if value is true, and TRUE if it is false. ',
+ s_fdef_NOW: 'Returns the current date/time. ',
+ s_fdef_NPER: 'Returns the number of periods at which payments invested each period at the given rate with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period) has the given present value. ',
+ s_fdef_NPV: 'Returns the net present value of cash flows (which may be individual values and/or ranges) at the given rate. The flows are positive if income, negative if paid out, and are assumed at the end of each period. ',
+ s_fdef_ODD: 'Rounds the value up in magnitude to the nearest odd integer. ',
+ s_fdef_OR: 'True if any argument is true ',
+ s_fdef_PI: 'The value 3.1415926... ',
+ s_fdef_PMT: 'Returns the amount of each payment that must be invested at the given rate for the specified number of periods to have the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). ',
+ s_fdef_POWER: 'Returns the first value raised to the second value power. ',
+ s_fdef_PRODUCT: 'Returns the result of multiplying the numeric values. ',
+ s_fdef_PROPER: 'Returns the text value with the first letter of each word converted to uppercase and the others to lowercase. ',
+ s_fdef_PV: 'Returns the present value of the given number of payments each invested at the given rate, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). ',
+ s_fdef_RADIANS: 'Converts value in degrees into radians. ',
+ s_fdef_RATE: 'Returns the rate at which the given number of payments each invested at the given rate has the specified present value, with optional future value (default 0) and payment type (default 0 = at end of period, 1 = beginning of period). Uses an iterative process that will return #NUM! error if it does not converge. There may be more than one possible solution. Providing the optional guess value may help in certain situations where it does not converge or finds an inappropriate solution (the default guess is 10%). ',
+ s_fdef_REPLACE: 'Returns text1 with the specified number of characters starting from the specified position replaced by text2. ',
+ s_fdef_REPT: 'Returns the text repeated the specified number of times. ',
+ s_fdef_RIGHT: 'Returns the specified number of characters from the text value starting from the end. If count is omitted, 1 is assumed. ',
+ s_fdef_ROUND: 'Rounds the value to the specified number of decimal places. If precision is negative, then round to powers of 10. The default precision is 0 (round to integer). ',
+ s_fdef_ROWS: 'Returns the number of rows in the range. ',
+ s_fdef_SECOND: 'Returns the second portion of a time or date/time value (truncated to an integer). ',
+ s_fdef_SIN: 'Trigonometric sine function (value is in radians) ',
+ s_fdef_SLN: 'Returns the amount of depreciation at each period of time using the straight-line method. ',
+ s_fdef_SQRT: 'Square root of the value ',
+ s_fdef_STDEV: 'Returns the sample standard deviation of the numeric values. ',
+ s_fdef_STDEVP: 'Returns the standard deviation of the numeric values. ',
+ s_fdef_SUBSTITUTE: 'Returns text1 with the all occurrences of oldtext replaced by newtext. If occurrence is present, then only that occurrence is replaced. ',
+ s_fdef_SUM: 'Adds the numeric values. The values to the sum function may be ranges in the form similar to A1:B5. ',
+ s_fdef_SUMIF: 'Sums the numeric values of cells in the range that meet the criteria. The criteria may be a value (x, 15, 1+3) or a test (>25). If range2 is present, then range1 is tested and the corresponding range2 value is summed. ',
+ s_fdef_SYD: "Depreciation by Sum of Year's Digits method. ",
+ s_fdef_T: 'Returns the text value or else a null string. ',
+ s_fdef_TAN: 'Trigonometric tangent function (value is in radians) ',
+ s_fdef_TIME: 'Returns the time value given the specified hour, minute, and second. ',
+ s_fdef_TODAY: 'Returns the current date (an integer). Note: In this program, day 1 is December 31, 1899 and the year 1900 is not a leap year. Some programs use January 1, 1900, as day 1 and treat 1900 as a leap year. In both cases, though, dates on or after March 1, 1900, are the same. ',
+ s_fdef_TRIM: 'Returns the text value with leading, trailing, and repeated spaces removed. ',
+ s_fdef_TRUE: 'Returns the logical value true. ',
+ s_fdef_TRUNC: 'Truncates the value to the specified number of decimal places. If precision is negative, truncate to powers of 10. ',
+ s_fdef_UPPER: 'Returns the text value with all lowercase characters converted to uppercase. ',
+ s_fdef_VALUE: 'Converts the specified text value into a numeric value. Various forms that look like numbers (including digits followed by %, forms that look like dates, etc.) are handled. This may not handle all of the forms accepted by other spreadsheets and may be locale dependent. ',
+ s_fdef_VAR: 'Returns the sample variance of the numeric values. ',
+ s_fdef_VARP: 'Returns the variance of the numeric values. ',
+ s_fdef_VLOOKUP: 'Look for the matching value for the given value in the range and return the corresponding value in the cell specified by the column offset. If rangelookup is 1 (the default) and not 0, match if within numeric brackets (match>=value) instead of exact match. ',
+ s_fdef_WEEKDAY: 'Returns the day of week specified by the date value. If type is 1 (the default), Sunday is day and Saturday is day 7. If type is 2, Monday is day 1 and Sunday is day 7. If type is 3, Monday is day 0 and Sunday is day 6. ',
+ s_fdef_YEAR: 'Returns the year part of a date value. ',
+
+ s_farg_v: "value",
+ s_farg_vn: "value1, value2, ...",
+ s_farg_xy: "valueX, valueY",
+ s_farg_choose: "index, value1, value2, ...",
+ s_farg_range: "range",
+ s_farg_rangec: "range, criteria",
+ s_farg_date: "year, month, day",
+ s_farg_dfunc: "databaserange, fieldname, criteriarange",
+ s_farg_ddb: "cost, salvage, lifetime, period [, factor]",
+ s_farg_find: "string1, string2 [, start]",
+ s_farg_fv: "rate, n, payment, [pv, [paytype]]",
+ s_farg_hlookup: "value, range, row, [rangelookup]",
+ s_farg_iffunc: "logical-expression, true-value, false-value",
+ s_farg_index: "range, rownum, colnum",
+ s_farg_irr: "range, [guess]",
+ s_farg_tc: "text, count",
+ s_farg_log: "value, base",
+ s_farg_match: "value, range, [rangelookup]",
+ s_farg_mid: "text, start, length",
+ s_farg_nper: "rate, payment, pv, [fv, [paytype]]",
+ s_farg_npv: "rate, value1, value2, ...",
+ s_farg_pmt: "rate, n, pv, [fv, [paytype]]",
+ s_farg_pv: "rate, n, payment, [fv, [paytype]]",
+ s_farg_rate: "n, payment, pv, [fv, [paytype, [guess]]]",
+ s_farg_replace: "text1, start, length, text2",
+ s_farg_vp: "value, [precision]",
+ s_farg_valpre: "value, precision",
+ s_farg_csl: "cost, salvage, lifetime",
+ s_farg_cslp: "cost, salvage, lifetime, period",
+ s_farg_subs: "text1, oldtext, newtext [, occurrence]",
+ s_farg_sumif: "range1, criteria [, range2]",
+ s_farg_hms: "hour, minute, second",
+ s_farg_txt: "text",
+ s_farg_vlookup: "value, range, col, [rangelookup]",
+ s_farg_weekday: "date, [type]",
+ s_farg_dt: "date",
+
+ function_classlist: ["all", "stat", "lookup", "datetime", "financial", "test", "math", "text"], // order of function classes
+
+ s_fclass_all: "All",
+ s_fclass_stat: "Statistics",
+ s_fclass_lookup: "Lookup",
+ s_fclass_datetime: "Date & Time",
+ s_fclass_financial: "Financial",
+ s_fclass_test: "Test",
+ s_fclass_math: "Math",
+ s_fclass_text: "Text",
+
+ lastone: null
+
+ };
+
+// Default classnames for use with SocialCalc.ConstantsSetClasses:
+
+SocialCalc.ConstantsDefaultClasses = {
+ defaultComment: "",
+ defaultCommentNoGrid: "",
+ defaultHighlightTypeCursor: "",
+ defaultHighlightTypeRange: "",
+ defaultColname: "",
+ defaultSelectedColname: "",
+ defaultRowname: "",
+ defaultSelectedRowname: "",
+ defaultUpperLeft: "",
+ defaultSkippedCell: "",
+ defaultPaneDivider: "",
+ cteGriddiv: "", // this one has no Style version with it
+ defaultInputEcho: {classname: "", style: "filter:alpha(opacity=90);opacity:.9;"}, // so FireFox won't show warning
+ TCmain: "",
+ TCendcap: "",
+ TCpaneslider: "",
+ TClessbutton: "",
+ TCmorebutton: "",
+ TCscrollarea: "",
+ TCthumb: "",
+ TCPStrackingline: "",
+ TCTDFSthumbstatus: "",
+ TDpopupElement: ""
+ };
+
+//
+// SocialCalc.ConstantsSetClasses(prefix)
+//
+// This routine goes through all of the xyzClass/xyzStyle pairs and sets the Class to a default and
+// turns off the Style, if present. The prefix is put before each default.
+// The list of items to set is in SocialCalc.ConstantsDefaultClasses. The names there
+// correspond to the "xyz" parts. If there is a value, it is the default to set. If the
+// default is a null, no change is made. If the default is the null string (""), the
+// name of the item is used (e.g., "defaultComment" would use the classname "defaultComment").
+// If the default is an object, then it expects {classname: classname, style: stylestring} - this
+// lets you combine both.
+//
+
+SocialCalc.ConstantsSetClasses = function(prefix) {
+
+ var defaults = SocialCalc.ConstantsDefaultClasses;
+ var scc = SocialCalc.Constants;
+ var item;
+
+ prefix = prefix || "";
+
+ for (item in defaults) {
+ if (typeof defaults[item] == "string") {
+ scc[item+"Class"] = prefix + (defaults[item] || item);
+ if (scc[item+"Style"] !== undefined) {
+ scc[item+"Style"] = "";
+ }
+ }
+ else if (typeof defaults[item] == "object") {
+ scc[item+"Class"] = prefix + (defaults[item].classname || item);
+ scc[item+"Style"] = defaults[item].style;
+ }
+ }
+ }
+
diff --git a/web/socialcalcpopup.js b/web/socialcalcpopup.js
new file mode 100644
index 0000000..e527536
--- /dev/null
+++ b/web/socialcalcpopup.js
@@ -0,0 +1,1618 @@
+//
+/*
+// The module of the SocialCalc package for the optional popup menus in socialcalcspreadsheetcontrol.js
+//
+// (c) Copyright 2009 Socialtext, Inc.
+// All Rights Reserved.
+//
+// The contents of this file are subject to the Artistic License 2.0; you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at http://socialcalc.org/licenses/al-20/.
+//
+// Some of the other files in the SocialCalc package are licensed under
+// different licenses. Please note the licenses of the modules you use.
+//
+// Code History:
+//
+// Initially coded by Dan Bricklin of Software Garden, Inc., for Socialtext, Inc.
+//
+*/
+
+ var SocialCalc; // All values are stored in the master SocialCalc object
+ if (!SocialCalc) {
+ SocialCalc = {};
+ }
+
+ // The main Popup data -- there is only one set
+
+ SocialCalc.Popup = {};
+
+ // Routines and values for each type of control, indexed by type name
+ // The value for each is an object constructed as follows:
+ //
+ // Create = function(type, id, attribs)
+ // Initialize = function(type, id, data)
+ // SetValue = function(type, id, value)
+ // GetValue = function(type, id) returns value
+ // SetDisabled = function(type, id, t/f)
+ // Show = function(type, id)
+ // Hide = function(type, id)
+ // Cancel = function(type, id)
+ // Reset = function(type)
+ //
+ // data = object to hold type-specific data
+ //
+
+ SocialCalc.Popup.Types = {};
+
+ // Definitions for each individual control, indexed by id
+ // The value for each is an object constructed as follows:
+ //
+ // type: type name of the control
+ // value: current value of the control (usually a string, but can depend on type)
+ // data: object with type-specific items
+ //
+
+ SocialCalc.Popup.Controls = {};
+
+ // System-wide values of currently active control
+ //
+ // id: id of current control or null
+ //
+
+ SocialCalc.Popup.Current = {};
+
+ // Other values used by the Popup system
+ //
+
+ SocialCalc.Popup.imagePrefix = "images/sc-"; // image prefix
+
+ // Override this for localization
+
+ SocialCalc.Popup.LocalizeString = function(str) {return str;};
+
+
+// * * * * * * * * * * * * * * * *
+//
+// GENERAL ROUTINES
+//
+// * * * * * * * * * * * * * * * *
+
+//
+// SocialCalc.Popup.Create(type, id, attribs)
+//
+// Creates a control of type "type" as the children of document element "id" using "attribs"
+//
+
+SocialCalc.Popup.Create = function(type, id, attribs) {
+
+ var pt = SocialCalc.Popup.Types[type];
+ if (pt && pt.Create) {
+ pt.Create(type, id, attribs);
+ }
+
+ }
+
+
+//
+// SocialCalc.Popup.SetValue(id, value)
+//
+// Sets the value of control.
+//
+
+SocialCalc.Popup.SetValue = function(id, value) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+
+ if (!spc[id]) {alert("Unknown control "+id);return;}
+
+ var type = spc[id].type;
+ var pt = spt[type];
+ var spcdata = spc[id].data;
+
+ if (pt && pt.Create) {
+ pt.SetValue(type, id, value);
+ if (spcdata.attribs && spcdata.attribs.changedcallback) {
+ spcdata.attribs.changedcallback(spcdata.attribs, id, value);
+ }
+ }
+
+ }
+
+
+//
+// SocialCalc.Popup.SetDisabled(id, disabled)
+//
+// Sets whether the control is disabled (true) or not (false).
+//
+
+SocialCalc.Popup.SetDisabled = function(id, disabled) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+
+ if (!spc[id]) {alert("Unknown control "+id);return;}
+
+ var type = spc[id].type;
+
+ var pt = spt[type];
+ if (pt && pt.Create) {
+ if (sp.Current.id && id == sp.Current.id) {
+ pt.Hide(type, sp.Current.id);
+ sp.Current.id = null;
+ }
+ pt.SetDisabled(type, id, disabled);
+ }
+
+ }
+
+
+//
+// SocialCalc.Popup.GetValue(id)
+//
+// Returns the value of control.
+//
+
+SocialCalc.Popup.GetValue = function(id) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+
+ if (!spc[id]) {alert("Unknown control "+id);return;}
+
+ var type = spc[id].type;
+
+ var pt = spt[type];
+ if (pt && pt.Create) {
+ return pt.GetValue(type, id);
+ }
+
+ return null;
+
+ }
+
+
+//
+// SocialCalc.Popup.Initialize(id, data)
+//
+// Gives "data" to the appropriate initialization code.
+//
+
+SocialCalc.Popup.Initialize = function(id, data) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+
+ if (!spc[id]) {alert("Unknown control "+id);return;}
+
+ var type = spc[id].type;
+
+ var pt = spt[type];
+ if (pt && pt.Initialize) {
+ pt.Initialize(type, id, data);
+ }
+
+ }
+
+
+//
+// SocialCalc.Popup.Reset(type)
+//
+// Resets Popup, such as when turning to page.
+//
+
+SocialCalc.Popup.Reset = function(type) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+
+ if (spt[type].Reset) spt[type].Reset(type);
+
+ }
+
+
+//
+// SocialCalc.Popup.CClick(id)
+//
+// Should be called when the user clicks on a control to do the popup
+//
+
+SocialCalc.Popup.CClick = function(id) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+
+ if (!spc[id]) {alert("Unknown control "+id);return;}
+
+ if (spc[id].data && spc[id].data.disabled) return;
+
+ var type = spc[id].type;
+
+ var pt = spt[type];
+
+ if (sp.Current.id) {
+ spt[spc[sp.Current.id].type].Hide(type, sp.Current.id);
+ if (id == sp.Current.id) { // same one - done
+ sp.Current.id = null;
+ return;
+ }
+ }
+
+ if (pt && pt.Show) {
+ pt.Show(type, id);
+ }
+
+ sp.Current.id = id;
+
+ }
+
+
+//
+// SocialCalc.Popup.Close()
+//
+// Used to close any open popup.
+//
+
+SocialCalc.Popup.Close = function() {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+
+ if (!sp.Current.id) return;
+
+ sp.CClick(sp.Current.id);
+
+ }
+
+//
+// SocialCalc.Popup.Cancel()
+//
+// Closes Popup and restores old value
+//
+
+SocialCalc.Popup.Cancel = function() {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+
+ if (!sp.Current.id) return;
+
+ var type = spc[sp.Current.id].type;
+
+ var pt = spt[type];
+
+ pt.Cancel(type, sp.Current.id);
+
+ sp.Current.id = null;
+
+ }
+
+//
+// ele = SocialCalc.Popup.CreatePopupDiv(id, attribs)
+//
+// Utility function to create the main popup div of width attribs.width.
+// If attribs.title, create one with that text, and optionally attribs.moveable.
+//
+
+SocialCalc.Popup.CreatePopupDiv = function(id, attribs) {
+
+ var pos, ele;
+
+ var sp = SocialCalc.Popup;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ var main = document.createElement("div");
+ main.style.position = "absolute";
+
+ pos = SocialCalc.GetElementPositionWithScroll(spcdata.mainele);
+
+ main.style.top = (pos.top+spcdata.mainele.offsetHeight)+"px";
+ main.style.left = (pos.left)+"px";
+ main.style.zIndex = 100;
+ main.style.backgroundColor = "#FFF";
+ main.style.border = "1px solid black";
+
+ if (attribs.width) {
+ main.style.width = attribs.width;
+ }
+
+ spcdata.mainele.appendChild(main);
+
+ if (attribs.title) {
+ main.innerHTML = '<table cellspacing="0" cellpadding="0" style="border-bottom:1px solid black;"><tr>'+
+ '<td style="font-size:10px;cursor:default;width:100%;background-color:#999;color:#FFF;">'+attribs.title+'</td>'+
+ '<td style="font-size:10px;cursor:default;color:#666;" onclick="SocialCalc.Popup.Cancel();">&nbsp;X&nbsp;</td></tr></table>';
+
+ if (attribs.moveable) {
+ spcdata.dragregistered = main.firstChild.firstChild.firstChild.firstChild;
+ SocialCalc.DragRegister(spcdata.dragregistered, true, true, {MouseDown: SocialCalc.DragFunctionStart, MouseMove: SocialCalc.DragFunctionPosition,
+ MouseUp: SocialCalc.DragFunctionPosition,
+ Disabled: null, positionobj: main});
+ }
+ }
+
+ return main;
+
+ }
+
+//
+// SocialCalc.Popup.EnsurePosition(id, container)
+//
+// Utility function to make sure popup is positioned completely within container (both element objects)
+// and appropriate with respect to the main element controlling the popup.
+//
+
+SocialCalc.Popup.EnsurePosition = function(id, container) {
+
+ var sp = SocialCalc.Popup;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ var main = spcdata.mainele.firstChild;
+ if (!main) {alert("No main popup element firstChild.");return};
+ var popup = spcdata.popupele;
+
+ function GetLayoutValues(ele) {
+ var r = SocialCalc.GetElementPositionWithScroll(ele);
+ r.height = ele.offsetHeight;
+ r.width = ele.offsetWidth;
+ r.bottom = r.top+r.height;
+ r.right = r.left+r.width;
+ return r;
+ }
+
+ var p = GetLayoutValues(popup);
+ var c = GetLayoutValues(container);
+ var m = GetLayoutValues(main);
+ var t = 0; // type of placement
+//addmsg("popup t/r/b/l/h/w= "+p.top+"/"+p.right+"/"+p.bottom+"/"+p.left+"/"+p.height+"/"+p.width);
+//addmsg("container t/r/b/l/h/w= "+c.top+"/"+c.right+"/"+c.bottom+"/"+c.left+"/"+c.height+"/"+c.width);
+//addmsg("main t/r/b/l/h/w= "+m.top+"/"+m.right+"/"+m.bottom+"/"+m.left+"/"+m.height+"/"+m.width);
+
+ // Check various layout cases in priority order
+
+ if (m.bottom+p.height < c.bottom && m.left+p.width < c.right) { // normal case: room on bottom and right
+ popup.style.top = m.bottom + "px";
+ popup.style.left = m.left + "px";
+ t = 1;
+ }
+
+ else if (m.top-p.height > c.top && m.left+p.width < c.right) { // room on top and right
+ popup.style.top = (m.top-p.height) + "px";
+ popup.style.left = m.left + "px";
+ t = 2;
+ }
+
+ else if (m.bottom+p.height < c.bottom && m.right-p.width > c.left) { // room on bottom and left
+ popup.style.top = m.bottom + "px";
+ popup.style.left = (m.right-p.width) + "px";
+ t = 3;
+ }
+
+ else if (m.top-p.height > c.top && m.right-p.width > c.left) { // room on top and left
+ popup.style.top = (m.top-p.height) + "px";
+ popup.style.left = (m.right-p.width) + "px";
+ t = 4;
+ }
+
+ else if (m.bottom+p.height < c.bottom && p.width < c.width) { // room on bottom and middle
+ popup.style.top = m.bottom + "px";
+ popup.style.left = (c.left+Math.floor((c.width-p.width)/2)) + "px";
+ t = 5;
+ }
+
+ else if (m.top-p.height > c.top && p.width < c.width) { // room on top and middle
+ popup.style.top = (m.top-p.height) + "px";
+ popup.style.left = (c.left+Math.floor((c.width-p.width)/2)) + "px";
+ t = 6;
+ }
+
+ else if (p.height < c.height && m.right+p.width < c.right) { // room on middle and right
+ popup.style.top = (c.top+Math.floor((c.height-p.height)/2)) + "px";
+ popup.style.left = m.right + "px";
+ t = 7;
+ }
+
+ else if (p.height < c.height && m.left-p.width > c.left) { // room on middle and left
+ popup.style.top = (c.top+Math.floor((c.height-p.height)/2)) + "px";
+ popup.style.left = (m.left-p.width) + "px";
+ t = 8;
+ }
+
+ else { // nothing works, so leave as it is
+ }
+//addmsg("Popup layout "+t);
+
+}
+
+//
+// ele = SocialCalc.Popup.DestroyPopupDiv(ele, dragregistered)
+//
+// Utility function to get rid of the main popup div.
+//
+
+SocialCalc.Popup.DestroyPopupDiv = function(ele, dragregistered) {
+
+ if (!ele) return;
+
+ ele.innerHTML = "";
+
+ SocialCalc.DragUnregister(dragregistered); // OK to do this even if not registered
+
+ if (ele.parentNode) {
+ ele.parentNode.removeChild(ele);
+ }
+
+ }
+
+//
+// Color Utility Functions
+//
+
+SocialCalc.Popup.RGBToHex = function(val) {
+
+ var sp = SocialCalc.Popup;
+
+ if (val=="") {
+ return "000000";
+ }
+ var rgbvals = val.match(/(\d+)\D+(\d+)\D+(\d+)/);
+ if (rgbvals) {
+ return sp.ToHex(rgbvals[1])+sp.ToHex(rgbvals[2])+sp.ToHex(rgbvals[3]);
+ }
+ else {
+ return "000000";
+ }
+ }
+
+SocialCalc.Popup.HexDigits="0123456789ABCDEF";
+
+SocialCalc.Popup.ToHex = function(num) {
+ var sp = SocialCalc.Popup;
+ var first=Math.floor(num / 16);
+ var second=num % 16;
+ return sp.HexDigits.charAt(first)+sp.HexDigits.charAt(second);
+ }
+
+SocialCalc.Popup.FromHex = function(str) {
+
+ var sp = SocialCalc.Popup;
+ var first = sp.HexDigits.indexOf(str.charAt(0).toUpperCase());
+ var second = sp.HexDigits.indexOf(str.charAt(1).toUpperCase());
+ return ((first>=0)?first:0)*16+((second>=0)?second:0);
+ }
+
+SocialCalc.Popup.HexToRGB = function(val) {
+
+ var sp = SocialCalc.Popup;
+
+ return "rgb("+sp.FromHex(val.substring(1,3))+","+sp.FromHex(val.substring(3,5))+","+sp.FromHex(val.substring(5,7))+")";
+
+ }
+
+SocialCalc.Popup.makeRGB = function(r, g, b) {
+ return "rgb("+(r>0?r:0)+","+(g>0?g:0)+","+(b>0?b:0)+")";
+ }
+
+SocialCalc.Popup.splitRGB = function(rgb) {
+ var parts = rgb.match(/(\d+)\D+(\d+)\D+(\d+)\D/);
+ if (!parts) {
+ return {r:0, g:0, b:0};
+ }
+ else {
+ return {r: parts[1]-0, g: parts[2]-0, b: parts[3]-0};
+ }
+ }
+
+// * * * * * * * * * * * * * * * *
+//
+// ROUTINES FOR EACH TYPE
+//
+// * * * * * * * * * * * * * * * *
+
+//
+// List
+//
+// type: List
+// value: value of control,
+// display: "value to display",
+// custom: true if custom value,
+// disabled: t/f,
+// attribs: {
+// title: "popup title string",
+// moveable: t/f,
+// width: optional width, e.g., "100px",
+// ensureWithin: optional element object to ensure popup fits within if possible
+// changedcallback: optional function(attribs, id, newvalue),
+// ...
+// }
+// data: {
+// ncols: calculated number of columns
+// options: [
+// {o: option-name, v: value-to-return,
+// a: {option attribs} // optional: {skip: true, custom: true, cancel: true, newcol: true}
+// },
+// ...]
+// }
+//
+// popupele: gets popup element object when created
+// contentele: gets element created with all the content
+// listdiv: gets div with list of items
+// customele: gets input element with custom value
+// dragregistered: gets element, if any, registered as draggable
+//
+
+SocialCalc.Popup.Types.List = {};
+
+SocialCalc.Popup.Types.List.Create = function(type, id, attribs) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+
+ var spcid = {type: type, value: "", display: "", data: {}};
+ if (spc[id]) {alert("Already created "+id); return;}
+ spc[id] = spcid;
+ var spcdata = spcid.data;
+
+ spcdata.attribs = attribs || {};
+
+ var ele = document.getElementById(id);
+ if (!ele) {alert("Missing element "+id); return;}
+
+ spcdata.mainele = ele;
+
+ ele.innerHTML = '<input style="cursor:pointer;width:100px;font-size:smaller;" onfocus="this.blur();" onclick="SocialCalc.Popup.CClick(\''+id+'\');" value="">';
+
+ spcdata.options = []; // set to nothing - use Initialize to fill
+
+ }
+
+SocialCalc.Popup.Types.List.SetValue = function(type, id, value) {
+
+ var i;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ spcdata.value = value;
+ spcdata.custom = false;
+
+ for (i=0; i<spcdata.options.length; i++) {
+ o = spcdata.options[i];
+ if (o.a) {
+ if (o.a.skip || o.a.custom || o.a.cancel) {
+ continue;
+ }
+ }
+ if (o.v == spcdata.value) { // matches value
+ spcdata.display = o.o;
+ break;
+ }
+ }
+ if (i==spcdata.options.length) { // none found
+ spcdata.display = "Custom";
+ spcdata.custom = true;
+ }
+
+ if (spcdata.mainele && spcdata.mainele.firstChild) {
+ spcdata.mainele.firstChild.value = spcdata.display;
+ }
+
+ }
+
+
+SocialCalc.Popup.Types.List.SetDisabled = function(type, id, disabled) {
+
+ var i;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ spcdata.disabled = disabled;
+
+ if (spcdata.mainele && spcdata.mainele.firstChild) {
+ spcdata.mainele.firstChild.disabled = disabled;
+ }
+
+ }
+
+
+SocialCalc.Popup.Types.List.GetValue = function(type, id) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ return spcdata.value;
+
+ }
+
+
+// data is: {value: initial value, attribs: {attribs stuff}, options: [{o: option-name, v: value-to-return, a: optional-attribs}, ...]}
+
+SocialCalc.Popup.Types.List.Initialize = function(type, id, data) {
+
+ var a;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ for (a in data.attribs) {
+ spcdata.attribs[a] = data.attribs[a];
+ }
+
+ spcdata.options = data ? data.options : [];
+
+ if (data.value) { // if has a value, set to it
+ sp.SetValue(id, data.value);
+ }
+
+ }
+
+
+SocialCalc.Popup.Types.List.Reset = function(type) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+
+ if (sp.Current.id && spc[sp.Current.id].type == type) { // we have a popup
+ spt[type].Hide(type, sp.Current.id);
+ sp.Current.id = null;
+ }
+
+ }
+
+
+SocialCalc.Popup.Types.List.Show = function(type, id) {
+
+ var i, ele, o, bg;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data
+
+ var str = "";
+
+ spcdata.popupele = sp.CreatePopupDiv(id, spcdata.attribs);
+
+ if (spcdata.custom) {
+ str = SocialCalc.Popup.Types.List.MakeCustom(type, id);
+
+ ele = document.createElement("div");
+ ele.innerHTML = '<div style="cursor:default;padding:4px;background-color:#CCC;">'+str+'</div>';
+
+ spcdata.customele = ele.firstChild.firstChild.childNodes[1];
+ spcdata.listdiv = null;
+ spcdata.contentele = ele;
+ }
+ else {
+ str = SocialCalc.Popup.Types.List.MakeList(type, id);
+
+ ele = document.createElement("div");
+ ele.innerHTML = '<div style="cursor:default;padding:4px;">'+str+'</div>';
+
+ spcdata.customele = null;
+ spcdata.listdiv = ele.firstChild;
+ spcdata.contentele = ele;
+ }
+
+ if (spcdata.mainele && spcdata.mainele.firstChild) {
+ spcdata.mainele.firstChild.disabled = true;
+ }
+
+ spcdata.popupele.appendChild(ele);
+
+ if (spcdata.attribs.ensureWithin) {
+ SocialCalc.Popup.EnsurePosition(id, spcdata.attribs.ensureWithin);
+ }
+
+ }
+
+
+SocialCalc.Popup.Types.List.MakeList = function(type, id) {
+
+ var i, ele, o, bg;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data
+
+ var str = '<table cellspacing="0" cellpadding="0"><tr>';
+ var td = '<td style="vertical-align:top;">';
+
+ str += td;
+
+ spcdata.ncols = 1;
+
+ for (i=0; i<spcdata.options.length; i++) {
+ o = spcdata.options[i];
+ if (o.a) {
+ if ( o.a.newcol) {
+ str += '</td>'+td+"&nbsp;&nbsp;&nbsp;&nbsp;"+'</td>'+td;
+ spcdata.ncols += 1;
+ continue;
+ }
+ if (o.a.skip) {
+ str += '<div style="font-size:x-small;white-space:nowrap;">'+o.o+'</div>';
+ continue;
+ }
+ }
+ if (o.v == spcdata.value && !(o.a && (o.a.custom || o.a.cancel))) { // matches value
+ bg = "background-color:#DDF;";
+ }
+ else {
+ bg = "";
+ }
+ str += '<div style="font-size:x-small;white-space:nowrap;'+bg+'" onclick="SocialCalc.Popup.Types.List.ItemClicked(\''+id+'\',\''+i+'\');" onmousemove="SocialCalc.Popup.Types.List.MouseMove(\''+id+'\',this);">'+o.o+'</div>';
+ }
+
+ str += "</td></tr></table>";
+
+ return str;
+
+ }
+
+
+SocialCalc.Popup.Types.List.MakeCustom = function(type, id) {
+
+ var SPLoc = SocialCalc.Popup.LocalizeString;
+
+ var i, ele, o, bg;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ var style = 'style="font-size:smaller;"';
+
+ var str = "";
+
+ var val = spcdata.value;
+ val = SocialCalc.special_chars(val);
+
+ str = '<div style="white-space:nowrap;"><br>'+
+ '<input id="customvalue" value="'+val+'"><br><br>'+
+ '<input '+style+' type="button" value="'+SPLoc("OK")+'" onclick="SocialCalc.Popup.Types.List.CustomOK(\''+id+'\');return false;">'+
+ '<input '+style+' type="button" value="'+SPLoc("List")+'" onclick="SocialCalc.Popup.Types.List.CustomToList(\''+id+'\');">'+
+ '<input '+style+' type="button" value="'+SPLoc("Cancel")+'" onclick="SocialCalc.Popup.Close();">'+
+ '<br></div>';
+
+ return str;
+
+ }
+
+
+SocialCalc.Popup.Types.List.ItemClicked = function(id, num) {
+
+ var oele, str, nele;
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ var a = spcdata.options[num].a;
+
+ if (a && a.custom) {
+ oele = spcdata.contentele;
+ str = SocialCalc.Popup.Types.List.MakeCustom("List", id);
+ nele = document.createElement("div");
+ nele.innerHTML = '<div style="cursor:default;padding:4px;background-color:#CCC;">'+str+'</div>';
+ spcdata.customele = nele.firstChild.firstChild.childNodes[1];
+ spcdata.listdiv = null;
+ spcdata.contentele = nele;
+ spcdata.popupele.replaceChild(nele, oele);
+ if (spcdata.attribs.ensureWithin) {
+ SocialCalc.Popup.EnsurePosition(id, spcdata.attribs.ensureWithin);
+ }
+ return;
+ }
+
+ if (a && a.cancel) {
+ SocialCalc.Popup.Close();
+ return;
+ }
+
+ SocialCalc.Popup.SetValue(id, spcdata.options[num].v);
+
+ SocialCalc.Popup.Close();
+
+ }
+
+
+SocialCalc.Popup.Types.List.CustomToList = function(id) {
+
+ var oele, str, nele;
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ oele = spcdata.contentele;
+ str = SocialCalc.Popup.Types.List.MakeList("List", id);
+ nele = document.createElement("div");
+ nele.innerHTML = '<div style="cursor:default;padding:4px;">'+str+'</div>';
+ spcdata.customele = null;
+ spcdata.listdiv = nele.firstChild;
+ spcdata.contentele = nele;
+ spcdata.popupele.replaceChild(nele, oele);
+
+ if (spcdata.attribs.ensureWithin) {
+ SocialCalc.Popup.EnsurePosition(id, spcdata.attribs.ensureWithin);
+ }
+ }
+
+
+SocialCalc.Popup.Types.List.CustomOK = function(id) {
+
+ var i, c;
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ SocialCalc.Popup.SetValue(id, spcdata.customele.value);
+
+ SocialCalc.Popup.Close();
+
+ }
+
+
+SocialCalc.Popup.Types.List.MouseMove = function(id, ele) {
+
+ var col, i, c;
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ var list = spcdata.listdiv;
+
+ if (!list) return;
+
+ var rowele = list.firstChild.firstChild.firstChild; // div.table.tbody.tr
+
+ for (col=0; col<spcdata.ncols; col++) {
+ for (i=0; i<rowele.childNodes[col*2].childNodes.length; i++) {
+ rowele.childNodes[col*2].childNodes[i].style.backgroundColor = "#FFF";
+ }
+ }
+
+ ele.style.backgroundColor = "#DDF";
+
+ }
+
+SocialCalc.Popup.Types.List.Hide = function(type, id) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ sp.DestroyPopupDiv(spcdata.popupele, spcdata.dragregistered);
+ spcdata.popupele = null;
+
+ if (spcdata.mainele && spcdata.mainele.firstChild) {
+ spcdata.mainele.firstChild.disabled = false;
+ }
+
+ }
+
+SocialCalc.Popup.Types.List.Cancel = function(type, id) {
+
+ SocialCalc.Popup.Types.List.Hide(type, id);
+
+ }
+
+
+//
+// ColorChooser
+//
+// type: ColorChooser
+// value: value of control as "rgb(r,g,b)" or "" if default,
+// oldvalue: starting value to reset to on close,
+// display: "value to display" as hex color value,
+// custom: true if custom value,
+// disabled: t/f,
+// attribs: {
+// title: "popup title string",
+// moveable: t/f,
+// width: optional width, e.g., "100px", of popup chooser
+// ensureWithin: optional element object to ensure popup fits within if possible
+// sampleWidth: optional width, e.g., "20px",
+// sampleHeight: optional height, e.g., "20px",
+// backgroundImage: optional background image for sample (transparent where want to show current color), e.g., "colorbg.gif"
+// backgroundImageDefault: optional background image for sample when default (transparent shows white)
+// backgroundImageDisabled: optional background image for sample when disabled (transparent shows gray)
+// changedcallback: optional function(attribs, id, newvalue),
+// ...
+// }
+// data: {
+// }
+//
+// popupele: gets popup element object when created
+// contentele: gets element created with all the content
+// customele: gets input element with custom value
+//
+
+SocialCalc.Popup.Types.ColorChooser = {};
+
+SocialCalc.Popup.Types.ColorChooser.Create = function(type, id, attribs) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+
+ var spcid = {type: type, value: "", display: "", data: {}};
+ if (spc[id]) {alert("Already created "+id); return;}
+ spc[id] = spcid;
+ var spcdata = spcid.data;
+
+ spcdata.attribs = attribs || {};
+ var spca = spcdata.attribs;
+
+ spcdata.value = "";
+
+ var ele = document.getElementById(id);
+ if (!ele) {alert("Missing element "+id); return;}
+
+ spcdata.mainele = ele;
+
+ ele.innerHTML = '<div style="cursor:pointer;border:1px solid black;vertical-align:top;width:'+
+ (spca.sampleWidth || '15px')+';height:'+(spca.sampleHeight || '15px')+
+ ';" onclick="SocialCalc.Popup.Types.ColorChooser.ControlClicked(\''+id+'\');">&nbsp;</div>';
+
+ }
+
+SocialCalc.Popup.Types.ColorChooser.SetValue = function(type, id, value) {
+
+ var i, img, pos;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+ var spca = spcdata.attribs;
+
+ spcdata.value = value;
+ spcdata.custom = false;
+
+ if (spcdata.mainele && spcdata.mainele.firstChild) {
+ if (spcdata.value) {
+ spcdata.mainele.firstChild.style.backgroundColor = spcdata.value;
+ if (spca.backgroundImage) {
+ img = "url("+sp.imagePrefix+spca.backgroundImage+")";
+ }
+ else {
+ img = "";
+ }
+ pos = "center center";
+ }
+ else {
+ spcdata.mainele.firstChild.style.backgroundColor = "#FFF";
+ if (spca.backgroundImageDefault) {
+ img = "url("+sp.imagePrefix+spca.backgroundImageDefault+")";
+ pos = "center center";
+ }
+ else {
+ img = "url("+sp.imagePrefix+"defaultcolor.gif)";
+ pos = "left top";
+ }
+ }
+ spcdata.mainele.firstChild.style.backgroundPosition = pos;
+ spcdata.mainele.firstChild.style.backgroundImage = img;
+ }
+
+ }
+
+
+SocialCalc.Popup.Types.ColorChooser.SetDisabled = function(type, id, disabled) {
+
+ var i;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+ var spca = spcdata.attribs;
+
+ spcdata.disabled = disabled;
+
+ if (spcdata.mainele && spcdata.mainele.firstChild) {
+ if (disabled) {
+ spcdata.mainele.firstChild.style.backgroundColor = "#DDD";
+ if (spca.backgroundImageDisabled) {
+ img = "url("+sp.imagePrefix+spca.backgroundImageDisabled+")";
+ pos = "center center";
+ }
+ else {
+ img = "url("+sp.imagePrefix+"defaultcolor.gif)";
+ pos = "left top";
+ }
+ spcdata.mainele.firstChild.style.backgroundPosition = pos;
+ spcdata.mainele.firstChild.style.backgroundImage = img;
+ }
+ else {
+ sp.SetValue(id, spcdata.value);
+ }
+ }
+
+ }
+
+
+SocialCalc.Popup.Types.ColorChooser.GetValue = function(type, id) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ return spcdata.value;
+
+ }
+
+
+SocialCalc.Popup.Types.ColorChooser.Initialize = function(type, id, data) {
+
+ var a;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ for (a in data.attribs) {
+ spcdata.attribs[a] = data.attribs[a];
+ }
+
+ if (data.value) { // if has a value, set to it
+ sp.SetValue(id, data.value);
+ }
+
+ }
+
+
+SocialCalc.Popup.Types.ColorChooser.Reset = function(type) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+
+ if (sp.Current.id && spc[sp.Current.id].type == type) { // we have a popup
+ spt[type].Hide(type, sp.Current.id);
+ sp.Current.id = null;
+ }
+
+ }
+
+
+SocialCalc.Popup.Types.ColorChooser.Show = function(type, id) {
+
+ var i, ele, mainele;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data
+
+ var str = "";
+
+ spcdata.oldvalue = spcdata.value; // remember starting value
+
+ spcdata.popupele = sp.CreatePopupDiv(id, spcdata.attribs);
+
+ if (spcdata.custom) {
+ str = SocialCalc.Popup.Types.ColorChooser.MakeCustom(type, id);
+
+ ele = document.createElement("div");
+ ele.innerHTML = '<div style="cursor:default;padding:4px;background-color:#CCC;">'+str+'</div>';
+
+ spcdata.customele = ele.firstChild.firstChild.childNodes[2];
+ spcdata.contentele = ele;
+ }
+ else {
+ mainele = SocialCalc.Popup.Types.ColorChooser.CreateGrid(type, id);
+
+ ele = document.createElement("div");
+ ele.style.padding = "3px";
+ ele.style.backgroundColor = "#CCC";
+ ele.appendChild(mainele);
+
+ spcdata.customele = null;
+ spcdata.contentele = ele;
+ }
+
+ spcdata.popupele.appendChild(ele);
+
+ if (spcdata.attribs.ensureWithin) {
+ SocialCalc.Popup.EnsurePosition(id, spcdata.attribs.ensureWithin);
+ }
+
+ }
+
+
+SocialCalc.Popup.Types.ColorChooser.MakeCustom = function(type, id) {
+
+ var i, ele, o, bg;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ var SPLoc = sp.LocalizeString;
+
+ var style = 'style="font-size:smaller;"';
+
+ var str = "";
+
+ str = '<div style="white-space:nowrap;"><br>'+
+ '#<input id="customvalue" style="width:75px;" value="'+spcdata.value+'"><br><br>'+
+ '<input '+style+' type="button" value="'+SPLoc("OK")+'" onclick="SocialCalc.Popup.Types.ColorChooser.CustomOK(\''+id+'\');return false;">'+
+ '<input '+style+' type="button" value="'+SPLoc("Grid")+'" onclick="SocialCalc.Popup.Types.ColorChooser.CustomToGrid(\''+id+'\');">'+
+ '<br></div>';
+
+ return str;
+
+ }
+
+
+SocialCalc.Popup.Types.ColorChooser.ItemClicked = function(id, num) {
+
+ var oele, str, nele;
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ SocialCalc.Popup.Close();
+
+ }
+
+
+SocialCalc.Popup.Types.ColorChooser.CustomToList = function(id) {
+
+ var oele, str, nele;
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ }
+
+
+SocialCalc.Popup.Types.ColorChooser.CustomOK = function(id) {
+
+ var i, c;
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ sp.SetValue(id, spcdata.customele.value);
+
+ sp.Close();
+
+ }
+
+
+SocialCalc.Popup.Types.ColorChooser.Hide = function(type, id) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ sp.DestroyPopupDiv(spcdata.popupele, spcdata.dragregistered);
+ spcdata.popupele = null;
+
+ }
+
+
+SocialCalc.Popup.Types.ColorChooser.Cancel = function(type, id) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ sp.SetValue(id, spcdata.oldvalue); // reset to old value
+
+ SocialCalc.Popup.Types.ColorChooser.Hide(type, id);
+
+ }
+
+
+SocialCalc.Popup.Types.ColorChooser.CreateGrid = function (type, id) {
+
+ var ele, pos, row, rowele, col, g;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var SPLoc = sp.LocalizeString;
+ var spcdata = spc[id].data;
+ spcdata.grid = {};
+ var grid = spcdata.grid;
+
+ var mainele = document.createElement("div");
+
+ ele = document.createElement("table");
+ ele.cellSpacing = 0;
+ ele.cellPadding = 0;
+ ele.style.width = "100px";
+ grid.table = ele;
+
+ ele = document.createElement("tbody");
+ grid.table.appendChild(ele);
+ grid.tbody = ele;
+
+ for (row=0; row<16; row++) {
+ rowele = document.createElement("tr");
+ for (col=0; col<5; col++) {
+ g = {};
+ grid[row+","+col] = g;
+ ele = document.createElement("td");
+ ele.style.fontSize = "1px";
+ ele.innerHTML = "&nbsp;";
+ ele.style.height = "10px";
+ if (col<=1) {
+ ele.style.width = "17px";
+ ele.style.borderRight = "3px solid white";
+ }
+ else {
+ ele.style.width = "20px";
+ ele.style.backgroundRepeat = "no-repeat";
+ }
+ rowele.appendChild(ele);
+ g.ele = ele;
+ }
+ grid.tbody.appendChild(rowele);
+ }
+ mainele.appendChild(grid.table);
+
+ ele = document.createElement("div");
+ ele.style.marginTop = "3px";
+ ele.innerHTML = '<table cellspacing="0" cellpadding="0"><tr>'+
+ '<td style="width:17px;background-color:#FFF;background-image:url('+sp.imagePrefix+'defaultcolor.gif);height:16px;font-size:10px;cursor:pointer;" title="'+SPLoc("Default")+'">&nbsp;</td>'+
+ '<td style="width:23px;height:16px;font-size:10px;text-align:center;cursor:pointer;" title="'+SPLoc("Custom")+'">#</td>'+
+ '<td style="width:60px;height:16px;font-size:10px;text-align:center;cursor:pointer;">'+SPLoc("OK")+'</td>'+
+ '</tr></table>';
+ grid.defaultbox = ele.firstChild.firstChild.firstChild.childNodes[0];
+ grid.defaultbox.onclick = spt.ColorChooser.DefaultClicked;
+ grid.custom = ele.firstChild.firstChild.firstChild.childNodes[1];
+ grid.custom.onclick = spt.ColorChooser.CustomClicked;
+ grid.msg = ele.firstChild.firstChild.firstChild.childNodes[2];
+ grid.msg.onclick = spt.ColorChooser.CloseOK;
+ mainele.appendChild(ele);
+
+ grid.table.onmousedown = spt.ColorChooser.GridMouseDown;
+
+ spt.ColorChooser.DetermineColors(id);
+ spt.ColorChooser.SetColors(id);
+
+ return mainele;
+
+ }
+
+SocialCalc.Popup.Types.ColorChooser.gridToG = function(grid, row, col) {
+
+ return grid[row+","+col];
+
+ }
+
+SocialCalc.Popup.Types.ColorChooser.DetermineColors = function(id) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var sptc = spt.ColorChooser;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+ var grid = spcdata.grid;
+
+ var col, row;
+ var rgb = sp.splitRGB(spcdata.value);
+ var color;
+
+ col = 2;
+ row = 16-Math.floor((rgb.r+16)/16);
+ grid["selectedrow"+col] = row;
+ for (row=0; row<16; row++) {
+ sptc.gridToG(grid,row,col).rgb = sp.makeRGB(17*(15-row),0,0);
+ }
+
+ col = 3;
+ row = 16-Math.floor((rgb.g+16)/16);
+ grid["selectedrow"+col] = row;
+ for (row=0; row<16; row++) {
+ sptc.gridToG(grid,row,col).rgb = sp.makeRGB(0,17*(15-row),0);
+ }
+
+ col = 4;
+ row = 16-Math.floor((rgb.b+16)/16);
+ grid["selectedrow"+col] = row;
+ for (row=0; row<16; row++) {
+ sptc.gridToG(grid,row,col).rgb = sp.makeRGB(0,0,17*(15-row));
+ }
+
+ col = 1;
+ for (row=0; row<16; row++) {
+ sptc.gridToG(grid,row,col).rgb = sp.makeRGB(17*(15-row),17*(15-row),17*(15-row));
+ }
+
+ col = 0;
+ var steps = [0, 68, 153, 204, 255];
+ var commonrgb = ["400", "310", "420", "440", "442", "340", "040", "042", "032", "044", "024", "004", "204", "314", "402", "414"];
+ var x;
+ for (row=0; row<16; row++) {
+ x = commonrgb[row];
+ sptc.gridToG(grid,row,col).rgb = "rgb("+steps[x.charAt(0)-0]+","+steps[x.charAt(1)-0]+","+steps[x.charAt(2)-0]+")";
+ }
+
+ }
+
+SocialCalc.Popup.Types.ColorChooser.SetColors = function(id) {
+
+ var row, col, g, ele, rgb;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var sptc = spt.ColorChooser;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+ var grid = spcdata.grid;
+
+ for (row=0; row<16; row++) {
+ for (col=0; col<5; col++) {
+ g = sptc.gridToG(grid,row, col);
+ g.ele.style.backgroundColor = g.rgb;
+ g.ele.title = sp.RGBToHex(g.rgb);
+ if (grid["selectedrow"+col]==row) {
+ g.ele.style.backgroundImage = "url("+sp.imagePrefix+"chooserarrow.gif)";
+ }
+ else {
+ g.ele.style.backgroundImage = "";
+ }
+ }
+ }
+
+ sp.SetValue(id, spcdata.value);
+
+ grid.msg.style.backgroundColor = spcdata.value;
+ rgb = sp.splitRGB(spcdata.value || "rgb(255,255,255)");
+ if (rgb.r+rgb.g+rgb.b < 220) {
+ grid.msg.style.color = "#FFF";
+ }
+ else {
+ grid.msg.style.color = "#000";
+ }
+ if (!spcdata.value) { // default
+ grid.msg.style.backgroundColor = "#FFF";
+ grid.msg.style.backgroundImage = "url("+sp.imagePrefix+"defaultcolor.gif)";
+ grid.msg.title = "Default";
+ }
+ else {
+ grid.msg.style.backgroundImage = "";
+ grid.msg.title = sp.RGBToHex(spcdata.value);
+ }
+
+ }
+
+SocialCalc.Popup.Types.ColorChooser.GridMouseDown = function(e) {
+
+ var event = e || window.event;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var sptc = spt.ColorChooser;
+ var spc = sp.Controls;
+
+ var id = sp.Current.id;
+ if (!id) return;
+
+ var spcdata = spc[id].data;
+ var grid = spcdata.grid;
+
+ switch (event.type) {
+ case "mousedown":
+ grid.mousedown = true;
+ break;
+ case "mouseup":
+ grid.mousedown = false;
+ break;
+ case "mousemove":
+ if (!grid.mousedown) {
+ return;
+ }
+ break;
+ }
+
+ var viewport = SocialCalc.GetViewportInfo();
+ var clientX = event.clientX + viewport.horizontalScroll;
+ var clientY = event.clientY + viewport.verticalScroll;
+ var gpos = SocialCalc.GetElementPosition(grid.table);
+ var row = Math.floor((clientY-gpos.top-2)/10); // -2 is to split the diff btw IE & FF
+ row = row < 0 ? 0 : row;
+ var col = Math.floor((clientX-gpos.left)/20);
+ row = row < 0 ? 0 : (row > 15 ? 15 : row);
+ col = col < 0 ? 0 : (col > 4 ? 4 : col);
+ var color = sptc.gridToG(grid,row,col).ele.style.backgroundColor;
+ var newrgb = sp.splitRGB(color);
+ var oldrgb = sp.splitRGB(spcdata.value);
+
+ switch (col) {
+ case 2:
+ spcdata.value = sp.makeRGB(newrgb.r, oldrgb.g, oldrgb.b);
+ break;
+ case 3:
+ spcdata.value = sp.makeRGB(oldrgb.r, newrgb.g, oldrgb.b);
+ break;
+ case 4:
+ spcdata.value = sp.makeRGB(oldrgb.r, oldrgb.g, newrgb.b);
+ break;
+ case 0:
+ case 1:
+ spcdata.value = color;
+ }
+
+ sptc.DetermineColors(id);
+ sptc.SetColors(id);
+
+ }
+
+
+SocialCalc.Popup.Types.ColorChooser.ControlClicked = function(id) {
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var sptc = spt.ColorChooser;
+ var spc = sp.Controls;
+
+ var cid = sp.Current.id;
+ if (!cid || id != cid) {
+ sp.CClick(id);
+ return;
+ }
+
+ sptc.CloseOK();
+
+ }
+
+SocialCalc.Popup.Types.ColorChooser.DefaultClicked = function(e) {
+
+ var event = e || window.event;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var sptc = spt.ColorChooser;
+ var spc = sp.Controls;
+
+ var id = sp.Current.id;
+ if (!id) return;
+
+ var spcdata = spc[id].data;
+
+ spcdata.value = "";
+ SocialCalc.Popup.SetValue(id, spcdata.value);
+
+ SocialCalc.Popup.Close();
+
+ }
+
+SocialCalc.Popup.Types.ColorChooser.CustomClicked = function(e) {
+
+ var event = e || window.event;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var sptc = spt.ColorChooser;
+ var spc = sp.Controls;
+
+ var id = sp.Current.id;
+ if (!id) return;
+
+ var spcdata = spc[id].data;
+
+ var oele, str, nele;
+
+ oele = spcdata.contentele;
+ str = SocialCalc.Popup.Types.ColorChooser.MakeCustom("ColorChooser", id);
+ nele = document.createElement("div");
+ nele.innerHTML = '<div style="cursor:default;padding:4px;background-color:#CCC;">'+str+'</div>';
+ spcdata.customele = nele.firstChild.firstChild.childNodes[2];
+ spcdata.contentele = nele;
+ spcdata.popupele.replaceChild(nele, oele);
+
+ spcdata.customele.value = sp.RGBToHex(spcdata.value);
+
+ if (spcdata.attribs.ensureWithin) {
+ SocialCalc.Popup.EnsurePosition(id, spcdata.attribs.ensureWithin);
+ }
+
+ }
+
+
+
+SocialCalc.Popup.Types.ColorChooser.CustomToGrid = function(id) {
+
+ var oele, str, nele;
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ SocialCalc.Popup.SetValue(id, sp.HexToRGB("#"+spcdata.customele.value));
+
+ var oele, mainele, nele;
+
+ oele = spcdata.contentele;
+ mainele = SocialCalc.Popup.Types.ColorChooser.CreateGrid("ColorChooser", id);
+ nele = document.createElement("div");
+ nele.style.padding = "3px";
+ nele.style.backgroundColor = "#CCC";
+ nele.appendChild(mainele);
+ spcdata.customele = null;
+ spcdata.contentele = nele;
+ spcdata.popupele.replaceChild(nele, oele);
+
+ if (spcdata.attribs.ensureWithin) {
+ SocialCalc.Popup.EnsurePosition(id, spcdata.attribs.ensureWithin);
+ }
+ }
+
+
+SocialCalc.Popup.Types.ColorChooser.CustomOK = function(id) {
+
+ var i, c;
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var spc = sp.Controls;
+ var spcdata = spc[id].data;
+
+ SocialCalc.Popup.SetValue(id, sp.HexToRGB("#"+spcdata.customele.value));
+
+ SocialCalc.Popup.Close();
+
+ }
+
+SocialCalc.Popup.Types.ColorChooser.CloseOK = function(e) {
+
+ var event = e || window.event;
+
+ var sp = SocialCalc.Popup;
+ var spt = sp.Types;
+ var sptc = spt.ColorChooser;
+ var spc = sp.Controls;
+
+ var id = sp.Current.id;
+ if (!id) return;
+
+ var spcdata = spc[id].data;
+
+ SocialCalc.Popup.SetValue(id, spcdata.value);
+
+ SocialCalc.Popup.Close();
+
+ }
+
diff --git a/web/socialcalcspreadsheetcontrol.js b/web/socialcalcspreadsheetcontrol.js
new file mode 100644
index 0000000..fa6712e
--- /dev/null
+++ b/web/socialcalcspreadsheetcontrol.js
@@ -0,0 +1,3551 @@
+//
+// SocialCalcSpreadsheetControl
+//
+/*
+// The code module of the SocialCalc package that lets you embed a spreadsheet
+// control with toolbar, etc., into a web page.
+//
+// (c) Copyright 2008, 2009 Socialtext, Inc.
+// All Rights Reserved.
+//
+*/
+
+/*
+
+LEGAL NOTICES REQUIRED BY THE COMMON PUBLIC ATTRIBUTION LICENSE:
+
+EXHIBIT A. Common Public Attribution License Version 1.0.
+
+The contents of this file are subject to the Common Public Attribution License Version 1.0 (the
+"License"); you may not use this file except in compliance with the License. You may obtain a copy
+of the License at http://socialcalc.org. The License is based on the Mozilla Public License Version 1.1 but
+Sections 14 and 15 have been added to cover use of software over a computer network and provide for
+limited attribution for the Original Developer. In addition, Exhibit A has been modified to be
+consistent with Exhibit B.
+
+Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+KIND, either express or implied. See the License for the specific language governing rights and
+limitations under the License.
+
+The Original Code is SocialCalc JavaScript SpreadsheetControl.
+
+The Original Developer is the Initial Developer.
+
+The Initial Developer of the Original Code is Socialtext, Inc. All portions of the code written by
+Socialtext, Inc., are Copyright (c) Socialtext, Inc. All Rights Reserved.
+
+Contributor: Dan Bricklin.
+
+
+EXHIBIT B. Attribution Information
+
+When the SpreadsheetControl is producing and/or controlling the display the Graphic Image must be
+displayed on the screen visible to the user in a manner comparable to that in the
+Original Code. The Attribution Phrase must be displayed as a "tooltip" or "hover-text" for
+that image. The image must be linked to the Attribution URL so as to access that page
+when clicked. If the user interface includes a prominent "about" display which includes
+factual prominent attribution in a form similar to that in the "about" display included
+with the Original Code, including Socialtext copyright notices and URLs, then the image
+need not be linked to the Attribution URL but the "tool-tip" is still required.
+
+Attribution Copyright Notice:
+
+ Copyright (C) 2008 Socialtext, Inc.
+ All Rights Reserved.
+
+Attribution Phrase (not exceeding 10 words): SocialCalc
+
+Attribution URL: http://www.socialcalc.org/
+
+Graphic Image: The contents of the sc-logo.gif file in the Original Code or
+a suitable replacement from http://www.socialcalc.org/licenses specified as
+being for SocialCalc.
+
+Display of Attribution Information is required in Larger Works which are defined
+in the CPAL as a work which combines Covered Code or portions thereof with code
+not governed by the terms of the CPAL.
+
+*/
+
+//
+// Some of the other files in the SocialCalc package are licensed under
+// different licenses. Please note the licenses of the modules you use.
+//
+// Code History:
+//
+// Initially coded by Dan Bricklin of Software Garden, Inc., for Socialtext, Inc.
+// Unless otherwise specified, referring to "SocialCalc" in comments refers to this
+// JavaScript version of the code, not the SocialCalc Perl code.
+//
+
+/*
+
+See the comments in the main SocialCalc code module file of the SocialCalc package.
+
+*/
+
+ var SocialCalc;
+ if (!SocialCalc) {
+ alert("Main SocialCalc code module needed");
+ SocialCalc = {};
+ }
+ if (!SocialCalc.TableEditor) {
+ alert("SocialCalc TableEditor code module needed");
+ }
+
+// *************************************
+//
+// SpreadsheetControl class:
+//
+// *************************************
+
+// Global constants:
+
+ SocialCalc.CurrentSpreadsheetControlObject = null; // right now there can only be one active at a time
+
+
+// Constructor:
+
+SocialCalc.SpreadsheetControl = function() {
+
+ var scc = SocialCalc.Constants;
+
+ // Properties:
+
+ this.parentNode = null;
+ this.spreadsheetDiv = null;
+ this.requestedHeight = 0;
+ this.requestedWidth = 0;
+ this.requestedSpaceBelow = 0;
+ this.height = 0;
+ this.width = 0;
+ this.viewheight = 0; // calculated amount for views below toolbar, etc.
+
+ // Tab definitions: An array where each tab is an object of the form:
+ //
+ // name: "name",
+ // text: "text-on-tab",
+ // html: "html-to-create div",
+ // replacements:
+ // "%s.": "SocialCalc", "%id.": spreadsheet.idPrefix, "%tbt.": spreadsheet.toolbartext
+ // Other replacements from spreadsheet.tabreplacements:
+ // replacementname: {regex: regular-expression-to-match-with-g, replacement: string}
+ // view: "viewname", // view to show when selected; "sheet" or missing/null is spreadsheet
+ // oncreate: function(spreadsheet, tab-name), // called when first created to initialize
+ // onclick: function(spreadsheet, tab-name), missing/null is sheet default
+ // onclickFocus: text, // spreadsheet.idPrefix+text is given the focus if present instead of normal KeyboardFocus
+ // or if text isn't a string, that value (e.g., true) is used for SocialCalc.CmdGotFocus
+ // onunclick: function(spreadsheet, tab-name), missing/null is sheet default
+
+ this.tabs = [];
+ this.tabnums = {}; // when adding tabs, add tab-name: array-index to this object
+ this.tabreplacements = {}; // see use above
+ this.currentTab = -1; // currently selected tab index in this.tabs or -1 (maintained by SocialCalc.SetTab)
+
+ // View definitions: An object where each view is an object of the form:
+ //
+ // name: "name", // localized when first set using SocialCalc.LocalizeString
+ // element: node-in-the-dom, // filled in when initialized
+ // replacements: {}, // see below
+ // html: "html-to-create div",
+ // replacements:
+ // "%s.": "SocialCalc", "%id.": spreadsheet.idPrefix, "%tbt.": spreadsheet.toolbartext, "%img.": spreadsheet.imagePrefix,
+ // SocialCalc.LocalizeSubstring replacements ("%loc!string!" and "%ssc!constant-name!")
+ // Other replacements from viewobject.replacements:
+ // replacementname: {regex: regular-expression-to-match-with-g, replacement: string}
+ // divStyle: attributes for sheet div (SocialCalc.setStyles format)
+ // oncreate: function(spreadsheet, viewobject), // called when first created to initialize
+ // needsresize: true/false/null, // if true, do resize calc after displaying
+ // onresize: function(spreadsheet, viewobject), // called if needs resize
+ // values: {} // optional values to share with onclick handlers, etc.
+ //
+ // There is always a "sheet" view.
+
+ this.views = {}; // {viewname: view-object, ...}
+
+ // Dynamic properties:
+
+ this.sheet = null;
+ this.context = null;
+ this.editor = null;
+
+ this.spreadsheetDiv = null;
+ this.editorDiv = null;
+
+ this.sortrange = ""; // remembered range for sort tab
+
+ this.moverange = ""; // remembered range from movefrom used by movepaste/moveinsert
+
+ // Constants:
+
+ this.idPrefix = "SocialCalc-"; // prefix added to element ids used here, should end in "-"
+ this.multipartBoundary = "SocialCalcSpreadsheetControlSave"; // boundary used by SpreadsheetControlCreateSpreadsheetSave
+ this.imagePrefix = scc.defaultImagePrefix; // prefix added to img src
+
+ this.toolbarbackground = scc.SCToolbarbackground;
+ this.tabbackground = scc.SCTabbackground;"background-color:#CCC;";
+ this.tabselectedCSS = scc.SCTabselectedCSS;
+ this.tabplainCSS = scc.SCTabplainCSS;
+ this.toolbartext = scc.SCToolbartext;
+
+ this.formulabarheight = scc.SCFormulabarheight; // in pixels, will contain a text input box
+
+ this.statuslineheight = scc.SCStatuslineheight; // in pixels
+ this.statuslineCSS = scc.SCStatuslineCSS;
+
+ // Callbacks:
+
+ this.ExportCallback = null; // a function called for Clipboard Export button: this.ExportCallback(spreadsheet_control_object)
+
+ // Initialization Code:
+
+ this.sheet = new SocialCalc.Sheet();
+ this.context = new SocialCalc.RenderContext(this.sheet);
+ this.context.showGrid=true;
+ this.context.showRCHeaders=true;
+ this.editor = new SocialCalc.TableEditor(this.context);
+ this.editor.StatusCallback.statusline =
+ {func: SocialCalc.SpreadsheetControlStatuslineCallback,
+ params: {statuslineid: this.idPrefix+"statusline",
+ recalcid1: this.idPrefix+"divider_recalc",
+ recalcid2: this.idPrefix+"button_recalc"}};
+
+ SocialCalc.CurrentSpreadsheetControlObject = this; // remember this for rendezvousing on events
+
+ this.editor.MoveECellCallback.movefrom = function(editor) {
+ var cr;
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ spreadsheet.context.cursorsuffix = "";
+ if (editor.range2.hasrange) {
+ if (editor.ecell.row==editor.range2.top && (editor.ecell.col<editor.range2.left || editor.ecell.col>editor.range2.right+1)) {
+ spreadsheet.context.cursorsuffix = "insertleft";
+ }
+ if (editor.ecell.col==editor.range2.left && (editor.ecell.row<editor.range2.top || editor.ecell.row>editor.range2.bottom+1)) {
+ spreadsheet.context.cursorsuffix = "insertup";
+ }
+ }
+ };
+
+ //to get the latest instance of the schedule spreadsheet command for the purpose of receiving the execute command
+ window.XO.register('execute',function(array){
+ try
+ {
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect")
+ //array = array.QueryInterface(Components.interfaces.nsIMutableArray)
+ window.XO.errorMessage=window.XO.errorMessage+'\nreached successfully in the register fn of execute'
+ if (array.length) {
+ window.XO.errorMessage=window.XO.errorMessage+'..........reaching inside the array.length';
+ var iter = array.enumerate()
+ var xp_arg1 = iter.getNext()
+ xp_arg1 = xp_arg1.QueryInterface(Components.interfaces.nsISupportsString)
+ xp_arg1= xp_arg1.toString()
+ var xp_arg2 = iter.getNext()
+ xp_arg2 = xp_arg2.QueryInterface(Components.interfaces.nsISupportsString)
+ xp_arg2= xp_arg2.toString()
+ //in order to call the current context schedulesheetcommand
+ window.XO.errorMessage=window.XO.errorMessage+'\ncalling the currentspreadsheet.schedulesheetcommand fn'
+ SocialCalc.CurrentSpreadsheetControlObject.context.sheetobj.ScheduleSheetCommands(xp_arg1,xp_arg2,true)
+ window.XO.errorMessage=window.XO.errorMessage+'\nreturned after calling the currentspreadsheet.schedulesheetcommand fn'
+
+
+ }//end of if(array.length)
+
+ else {window.XO.errorMessage=window.XO.errorMessage+'..........array is empty';}
+
+ }//end of try
+
+
+ catch(err)
+ {window.XO.errorMessage='here lies the problem'+err;//alert('here lies the problem'+err);
+
+ }//end of catch
+
+ })//end of window.XO.register
+
+ // formula bar buttons
+
+ this.formulabuttons = {
+ formulafunctions: {image: "formuladialog.gif", tooltip: "Functions", // tooltips are localized when set below
+ command: SocialCalc.SpreadsheetControl.DoFunctionList},
+ multilineinput: {image: "multilinedialog.gif", tooltip: "Multi-line Input Box",
+ command: SocialCalc.SpreadsheetControl.DoMultiline},
+ link: {image: "linkdialog.gif", tooltip: "Link Input Box",
+ command: SocialCalc.SpreadsheetControl.DoLink},
+ sum: {image: "sumdialog.gif", tooltip: "Auto Sum",
+ command: SocialCalc.SpreadsheetControl.DoSum}
+ }
+
+ // Default tabs:
+
+ // Edit
+
+ this.tabnums.edit = this.tabs.length;
+ this.tabs.push({name: "edit", text: "Edit", html:
+ ' <div id="%id.edittools" style="padding:10px 0px 0px 0px;">'+
+'&nbsp;<img id="%id.button_undo" src="%img.undo.gif" style="vertical-align:bottom;">'+
+' <img id="%id.button_redo" src="%img.redo.gif" style="vertical-align:bottom;">'+
+' &nbsp;<img src="%img.divider1.gif" style="vertical-align:bottom;">&nbsp; '+
+'<img id="%id.button_copy" src="%img.copy.gif" style="vertical-align:bottom;">'+
+' <img id="%id.button_cut" src="%img.cut.gif" style="vertical-align:bottom;">'+
+' <img id="%id.button_paste" src="%img.paste.gif" style="vertical-align:bottom;">'+
+' &nbsp;<img src="%img.divider1.gif" style="vertical-align:bottom;">&nbsp; '+
+'<img id="%id.button_delete" src="%img.delete.gif" style="vertical-align:bottom;">'+
+' <img id="%id.button_pasteformats" src="%img.pasteformats.gif" style="vertical-align:bottom;">'+
+' &nbsp;<img src="%img.divider1.gif" style="vertical-align:bottom;">&nbsp; '+
+'<img id="%id.button_filldown" src="%img.filldown.gif" style="vertical-align:bottom;">'+
+' <img id="%id.button_fillright" src="%img.fillright.gif" style="vertical-align:bottom;">'+
+' &nbsp;<img src="%img.divider1.gif" style="vertical-align:bottom;">&nbsp; '+
+'<img id="%id.button_movefrom" src="%img.movefromoff.gif" style="vertical-align:bottom;">'+
+' <img id="%id.button_movepaste" src="%img.movepasteoff.gif" style="vertical-align:bottom;">'+
+' <img id="%id.button_moveinsert" src="%img.moveinsertoff.gif" style="vertical-align:bottom;">'+
+' &nbsp;<img src="%img.divider1.gif" style="vertical-align:bottom;">&nbsp; '+
+'<img id="%id.button_alignleft" src="%img.alignleft.gif" style="vertical-align:bottom;">'+
+' <img id="%id.button_aligncenter" src="%img.aligncenter.gif" style="vertical-align:bottom;">'+
+' <img id="%id.button_alignright" src="%img.alignright.gif" style="vertical-align:bottom;">'+
+' &nbsp;<img src="%img.divider1.gif" style="vertical-align:bottom;">&nbsp; '+
+'<img id="%id.button_borderon" src="%img.borderson.gif" style="vertical-align:bottom;"> '+
+' <img id="%id.button_borderoff" src="%img.bordersoff.gif" style="vertical-align:bottom;"> '+
+' <img id="%id.button_swapcolors" src="%img.swapcolors.gif" style="vertical-align:bottom;"> '+
+' &nbsp;<img src="%img.divider1.gif" style="vertical-align:bottom;">&nbsp; '+
+'<img id="%id.button_merge" src="%img.merge.gif" style="vertical-align:bottom;"> '+
+' <img id="%id.button_unmerge" src="%img.unmerge.gif" style="vertical-align:bottom;"> '+
+' &nbsp;<img src="%img.divider1.gif" style="vertical-align:bottom;">&nbsp; '+
+'<img id="%id.button_insertrow" src="%img.insertrow.gif" style="vertical-align:bottom;"> '+
+' <img id="%id.button_insertcol" src="%img.insertcol.gif" style="vertical-align:bottom;"> '+
+'&nbsp; <img id="%id.button_deleterow" src="%img.deleterow.gif" style="vertical-align:bottom;"> '+
+' <img id="%id.button_deletecol" src="%img.deletecol.gif" style="vertical-align:bottom;"> '+
+' &nbsp;<img id="%id.divider_recalc" src="%img.divider1.gif" style="vertical-align:bottom;">&nbsp; '+
+'<img id="%id.button_recalc" src="%img.recalc.gif" style="vertical-align:bottom;"> '+
+ ' </div>',
+ oncreate: null, //function(spreadsheet, viewobject) {SocialCalc.DoCmd(null, "fill-rowcolstuff");},
+ onclick: null});
+
+ // Settings (Format)
+
+ this.tabnums.settings = this.tabs.length;
+ this.tabs.push({name: "settings", text: "Format", html:
+ '<div id="%id.settingstools" style="display:none;">'+
+ ' <div id="%id.sheetsettingstoolbar" style="display:none;">'+
+ ' <table cellspacing="0" cellpadding="0"><tr><td>'+
+ ' <div style="%tbt.">%loc!SHEET SETTINGS!:</div>'+
+ ' </td></tr><tr><td>'+
+ ' <input id="%id.settings-savesheet" type="button" value="%loc!Save!" onclick="SocialCalc.SettingsControlSave(\'sheet\');">'+
+ ' <input type="button" value="%loc!Cancel!" onclick="SocialCalc.SettingsControlSave(\'cancel\');">'+
+ ' <input type="button" value="%loc!Show Cell Settings!" onclick="SocialCalc.SpreadsheetControlSettingsSwitch(\'cell\');return false;">'+
+ ' </td></tr></table>'+
+ ' </div>'+
+ ' <div id="%id.cellsettingstoolbar" style="display:none;">'+
+ ' <table cellspacing="0" cellpadding="0"><tr><td>'+
+ ' <div style="%tbt.">%loc!CELL SETTINGS!: <span id="%id.settingsecell">&nbsp;</span></div>'+
+ ' </td></tr><tr><td>'+
+ ' <input id="%id.settings-savecell" type="button" value="%loc!Save!" onclick="SocialCalc.SettingsControlSave(\'cell\');">'+
+ ' <input type="button" value="%loc!Cancel!" onclick="SocialCalc.SettingsControlSave(\'cancel\');">'+
+ ' <input type="button" value="%loc!Show Sheet Settings!" onclick="SocialCalc.SpreadsheetControlSettingsSwitch(\'sheet\');return false;">'+
+ ' </td></tr></table>'+
+ ' </div>'+
+ '</div>',
+ view: "settings",
+ onclick: function(s, t) {
+ SocialCalc.SettingsControls.idPrefix = s.idPrefix; // used to get color chooser div
+ SocialCalc.SettingControlReset();
+ var sheetattribs = s.sheet.EncodeSheetAttributes();
+ var cellattribs = s.sheet.EncodeCellAttributes(s.editor.ecell.coord);
+ SocialCalc.SettingsControlLoadPanel(s.views.settings.values.sheetspanel, sheetattribs);
+ SocialCalc.SettingsControlLoadPanel(s.views.settings.values.cellspanel, cellattribs);
+ document.getElementById(s.idPrefix+"settingsecell").innerHTML = s.editor.ecell.coord;
+ SocialCalc.SpreadsheetControlSettingsSwitch("cell");
+ s.views.settings.element.style.height = s.viewheight+"px";
+ s.views.settings.element.firstChild.style.height = s.viewheight+"px";
+
+ var range; // set save message
+ if (s.editor.range.hasrange) {
+ range = SocialCalc.crToCoord(s.editor.range.left, s.editor.range.top) + ":" +
+ SocialCalc.crToCoord(s.editor.range.right, s.editor.range.bottom);
+ }
+ else {
+ range = s.editor.ecell.coord;
+ }
+ document.getElementById(s.idPrefix+"settings-savecell").value = SocialCalc.LocalizeString("Save to")+": "+range;
+ },
+ onclickFocus: true
+ });
+
+ this.views["settings"] = {name: "settings", values: {},
+ oncreate: function(s, viewobj) {
+ var scc = SocialCalc.Constants;
+
+ viewobj.values.sheetspanel = {
+// name: "sheet",
+ colorchooser: {id: s.idPrefix+"scolorchooser"},
+ formatnumber: {setting: "numberformat", type: "PopupList", id: s.idPrefix+"formatnumber",
+ initialdata: scc.SCFormatNumberFormats},
+ formattext: {setting: "textformat", type: "PopupList", id: s.idPrefix+"formattext",
+ initialdata: scc.SCFormatTextFormats},
+ fontfamily: {setting: "fontfamily", type: "PopupList", id: s.idPrefix+"fontfamily",
+ initialdata: scc.SCFormatFontfamilies},
+ fontlook: {setting: "fontlook", type: "PopupList", id: s.idPrefix+"fontlook",
+ initialdata: scc.SCFormatFontlook},
+ fontsize: {setting: "fontsize", type: "PopupList", id: s.idPrefix+"fontsize",
+ initialdata: scc.SCFormatFontsizes},
+ textalignhoriz: {setting: "textalignhoriz", type: "PopupList", id: s.idPrefix+"textalignhoriz",
+ initialdata: scc.SCFormatTextAlignhoriz},
+ numberalignhoriz: {setting: "numberalignhoriz", type: "PopupList", id: s.idPrefix+"numberalignhoriz",
+ initialdata: scc.SCFormatNumberAlignhoriz},
+ alignvert: {setting: "alignvert", type: "PopupList", id: s.idPrefix+"alignvert",
+ initialdata: scc.SCFormatAlignVertical},
+ textcolor: {setting: "textcolor", type: "ColorChooser", id: s.idPrefix+"textcolor"},
+ bgcolor: {setting: "bgcolor", type: "ColorChooser", id: s.idPrefix+"bgcolor"},
+ padtop: {setting: "padtop", type: "PopupList", id: s.idPrefix+"padtop",
+ initialdata: scc.SCFormatPadsizes},
+ padright: {setting: "padright", type: "PopupList", id: s.idPrefix+"padright",
+ initialdata: scc.SCFormatPadsizes},
+ padbottom: {setting: "padbottom", type: "PopupList", id: s.idPrefix+"padbottom",
+ initialdata: scc.SCFormatPadsizes},
+ padleft: {setting: "padleft", type: "PopupList", id: s.idPrefix+"padleft",
+ initialdata: scc.SCFormatPadsizes},
+ colwidth: {setting: "colwidth", type: "PopupList", id: s.idPrefix+"colwidth",
+ initialdata: scc.SCFormatColwidth},
+ recalc: {setting: "recalc", type: "PopupList", id: s.idPrefix+"recalc",
+ initialdata: scc.SCFormatRecalc}
+ };
+ viewobj.values.cellspanel = {
+ name: "cell",
+ colorchooser: {id: s.idPrefix+"scolorchooser"},
+ cformatnumber: {setting: "numberformat", type: "PopupList", id: s.idPrefix+"cformatnumber",
+ initialdata: scc.SCFormatNumberFormats},
+ cformattext: {setting: "textformat", type: "PopupList", id: s.idPrefix+"cformattext",
+ initialdata: scc.SCFormatTextFormats},
+ cfontfamily: {setting: "fontfamily", type: "PopupList", id: s.idPrefix+"cfontfamily",
+ initialdata: scc.SCFormatFontfamilies},
+ cfontlook: {setting: "fontlook", type: "PopupList", id: s.idPrefix+"cfontlook",
+ initialdata: scc.SCFormatFontlook},
+ cfontsize: {setting: "fontsize", type: "PopupList", id: s.idPrefix+"cfontsize",
+ initialdata: scc.SCFormatFontsizes},
+ calignhoriz: {setting: "alignhoriz", type: "PopupList", id: s.idPrefix+"calignhoriz",
+ initialdata: scc.SCFormatTextAlignhoriz},
+ calignvert: {setting: "alignvert", type: "PopupList", id: s.idPrefix+"calignvert",
+ initialdata: scc.SCFormatAlignVertical},
+ ctextcolor: {setting: "textcolor", type: "ColorChooser", id: s.idPrefix+"ctextcolor"},
+ cbgcolor: {setting: "bgcolor", type: "ColorChooser", id: s.idPrefix+"cbgcolor"},
+ cbt: {setting: "bt", type: "BorderSide", id: s.idPrefix+"cbt"},
+ cbr: {setting: "br", type: "BorderSide", id: s.idPrefix+"cbr"},
+ cbb: {setting: "bb", type: "BorderSide", id: s.idPrefix+"cbb"},
+ cbl: {setting: "bl", type: "BorderSide", id: s.idPrefix+"cbl"},
+ cpadtop: {setting: "padtop", type: "PopupList", id: s.idPrefix+"cpadtop",
+ initialdata: scc.SCFormatPadsizes},
+ cpadright: {setting: "padright", type: "PopupList", id: s.idPrefix+"cpadright",
+ initialdata: scc.SCFormatPadsizes},
+ cpadbottom: {setting: "padbottom", type: "PopupList", id: s.idPrefix+"cpadbottom",
+ initialdata: scc.SCFormatPadsizes},
+ cpadleft: {setting: "padleft", type: "PopupList", id: s.idPrefix+"cpadleft",
+ initialdata: scc.SCFormatPadsizes}
+ };
+
+ SocialCalc.SettingsControlInitializePanel(viewobj.values.sheetspanel);
+ SocialCalc.SettingsControlInitializePanel(viewobj.values.cellspanel);
+ },
+ replacements: {
+ itemtitle: {regex: /\%itemtitle\./g, replacement: 'style="padding:12px 10px 0px 10px;font-weight:bold;text-align:right;vertical-align:top;font-size:small;"'},
+ sectiontitle: {regex: /\%sectiontitle\./g, replacement: 'style="padding:16px 10px 0px 0px;font-weight:bold;vertical-align:top;font-size:small;color:#C00;"'},
+ parttitle: {regex: /\%parttitle\./g, replacement: 'style="font-weight:bold;font-size:x-small;padding:0px 0px 3px 0px;"'},
+ itembody: {regex: /\%itembody\./g, replacement: 'style="padding:12px 0px 0px 0px;vertical-align:top;font-size:small;"'},
+ bodypart: {regex: /\%bodypart\./g, replacement: 'style="padding:0px 10px 0px 0px;font-size:small;vertical-align:top;"'}
+ },
+ divStyle: "border:1px solid black;overflow:auto;",
+ html:
+ '<div id="%id.scolorchooser" style="display:none;position:absolute;z-index:20;"></div>'+
+'<table cellspacing="0" cellpadding="0">'+
+' <tr><td style="vertical-align:top;">'+
+'<table id="%id.sheetsettingstable" style="display:none;" cellspacing="0" cellpadding="0">'+
+'<tr>'+
+' <td %itemtitle.><br>%loc!Default Format!:</td>'+
+' <td %itembody.>'+
+' <table cellspacing="0" cellpadding="0"><tr>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Number!</div>'+
+' <span id="%id.formatnumber"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Text!</div>'+
+' <span id="%id.formattext"></span>'+
+' </td>'+
+' </tr></table>'+
+' </td>'+
+'</tr>'+
+'<tr>'+
+' <td %itemtitle.><br>%loc!Default Alignment!:</td>'+
+' <td %itembody.>'+
+' <table cellspacing="0" cellpadding="0"><tr>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Text Horizontal!</div>'+
+' <span id="%id.textalignhoriz"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Number Horizontal!</div>'+
+' <span id="%id.numberalignhoriz"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Vertical!</div>'+
+' <span id="%id.alignvert"></span>'+
+' </td>'+
+' </tr></table>'+
+' </td>'+
+'</tr>'+
+'<tr>'+
+' <td %itemtitle.><br>%loc!Default Font!:</td>'+
+' <td %itembody.>'+
+' <table cellspacing="0" cellpadding="0"><tr>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Family!</div>'+
+' <span id="%id.fontfamily"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Bold &amp; Italics!</div>'+
+' <span id="%id.fontlook"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Size!</div>'+
+' <span id="%id.fontsize"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Color!</div>'+
+' <div id="%id.textcolor"></div>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Background!</div>'+
+' <div id="%id.bgcolor"></div>'+
+' </td>'+
+' </tr></table>'+
+' </td>'+
+'</tr>'+
+'<tr>'+
+' <td %itemtitle.><br>%loc!Default Padding!:</td>'+
+' <td %itembody.>'+
+' <table cellspacing="0" cellpadding="0"><tr>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Top!</div>'+
+' <span id="%id.padtop"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Right!</div>'+
+' <span id="%id.padright"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Bottom!</div>'+
+' <span id="%id.padbottom"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Left!</div>'+
+' <span id="%id.padleft"></span>'+
+' </td>'+
+' </tr></table>'+
+' </td>'+
+'</tr>'+
+'<tr>'+
+' <td %itemtitle.><br>%loc!Default Column Width!:</td>'+
+' <td %itembody.>'+
+' <table cellspacing="0" cellpadding="0"><tr>'+
+' <td %bodypart.>'+
+' <div %parttitle.>&nbsp;</div>'+
+' <span id="%id.colwidth"></span>'+
+' </td>'+
+' </tr></table>'+
+' </td>'+
+'</tr>'+
+'<tr>'+
+' <td %itemtitle.><br>%loc!Recalculation!:</td>'+
+' <td %itembody.>'+
+' <table cellspacing="0" cellpadding="0"><tr>'+
+' <td %bodypart.>'+
+' <div %parttitle.>&nbsp;</div>'+
+' <span id="%id.recalc"></span>'+
+' </td>'+
+' </tr></table>'+
+' </td>'+
+'</tr>'+
+'</table>'+
+'<table id="%id.cellsettingstable" cellspacing="0" cellpadding="0">'+
+'<tr>'+
+' <td %itemtitle.><br>%loc!Format!:</td>'+
+' <td %itembody.>'+
+' <table cellspacing="0" cellpadding="0"><tr>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Number!</div>'+
+' <span id="%id.cformatnumber"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Text!</div>'+
+' <span id="%id.cformattext"></span>'+
+' </td>'+
+' </tr></table>'+
+' </td>'+
+'</tr>'+
+'<tr>'+
+' <td %itemtitle.><br>%loc!Alignment!:</td>'+
+' <td %itembody.>'+
+' <table cellspacing="0" cellpadding="0"><tr>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Horizontal!</div>'+
+' <span id="%id.calignhoriz"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Vertical!</div>'+
+' <span id="%id.calignvert"></span>'+
+' </td>'+
+' </tr></table>'+
+' </td>'+
+'</tr>'+
+'<tr>'+
+' <td %itemtitle.><br>%loc!Font!:</td>'+
+' <td %itembody.>'+
+' <table cellspacing="0" cellpadding="0"><tr>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Family!</div>'+
+' <span id="%id.cfontfamily"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Bold &amp; Italics!</div>'+
+' <span id="%id.cfontlook"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Size!</div>'+
+' <span id="%id.cfontsize"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Color!</div>'+
+' <div id="%id.ctextcolor"></div>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Background!</div>'+
+' <div id="%id.cbgcolor"></div>'+
+' </td>'+
+' </tr></table>'+
+' </td>'+
+'</tr>'+
+'<tr>'+
+' <td %itemtitle.><br>%loc!Borders!:</td>'+
+' <td %itembody.>'+
+' <table cellspacing="0" cellpadding="0">'+
+' <tr><td %bodypart. colspan="3"><div %parttitle.>%loc!Top Border!</div></td>'+
+' <td %bodypart. colspan="3"><div %parttitle.>%loc!Right Border!</div></td>'+
+' <td %bodypart. colspan="3"><div %parttitle.>%loc!Bottom Border!</div></td>'+
+' <td %bodypart. colspan="3"><div %parttitle.>%loc!Left Border!</div></td>'+
+' </tr><tr>'+
+' <td %bodypart.>'+
+' <input id="%id.cbt-onoff-bcb" onclick="SocialCalc.SettingsControlOnchangeBorder(this);" type="checkbox">'+
+' </td>'+
+' <td %bodypart.>'+
+' <div id="%id.cbt-color"></div>'+
+' </td>'+
+' <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>'+
+' <td %bodypart.>'+
+' <input id="%id.cbr-onoff-bcb" onclick="SocialCalc.SettingsControlOnchangeBorder(this);" type="checkbox">'+
+' </td>'+
+' <td %bodypart.>'+
+' <div id="%id.cbr-color"></div>'+
+' </td>'+
+' <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>'+
+' <td %bodypart.>'+
+' <input id="%id.cbb-onoff-bcb" onclick="SocialCalc.SettingsControlOnchangeBorder(this);" type="checkbox">'+
+' </td>'+
+' <td %bodypart.>'+
+' <div id="%id.cbb-color"></div>'+
+' </td>'+
+' <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>'+
+' <td %bodypart.>'+
+' <input id="%id.cbl-onoff-bcb" onclick="SocialCalc.SettingsControlOnchangeBorder(this);" type="checkbox">'+
+' </td>'+
+' <td %bodypart.>'+
+' <div id="%id.cbl-color"></div>'+
+' </td>'+
+' <td>&nbsp;&nbsp;&nbsp;&nbsp;</td>'+
+' </tr></table>'+
+' </td>'+
+'</tr>'+
+'<tr>'+
+' <td %itemtitle.><br>%loc!Padding!:</td>'+
+' <td %itembody.>'+
+' <table cellspacing="0" cellpadding="0"><tr>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Top!</div>'+
+' <span id="%id.cpadtop"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Right!</div>'+
+' <span id="%id.cpadright"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Bottom!</div>'+
+' <span id="%id.cpadbottom"></span>'+
+' </td>'+
+' <td %bodypart.>'+
+' <div %parttitle.>%loc!Left!</div>'+
+' <span id="%id.cpadleft"></span>'+
+' </td>'+
+' </tr></table>'+
+' </td>'+
+'</tr>'+
+'</table>'+
+' </td><td style="vertical-align:top;padding:12px 0px 0px 12px;">'+
+' <div style="width:100px;height:100px;overflow:hidden;border:1px solid black;background-color:#EEE;padding:6px;">'+
+' <table cellspacing="0" cellpadding="0"><tr>'+
+' <td id="sample-text" style="height:100px;width:100px;"><div>%loc!This is a<br>sample!</div><div>-1234.5</div></td>'+
+' </tr></table>'+
+' </div>'+
+' </td></tr></table>'+
+'<br>'
+ };
+
+ // Sort
+
+ this.tabnums.sort = this.tabs.length;
+ this.tabs.push({name: "sort", text: "Sort", html:
+ ' <div id="%id.sorttools" style="display:none;">'+
+ ' <table cellspacing="0" cellpadding="0"><tr>'+
+ ' <td style="vertical-align:top;padding-right:4px;width:160px;">'+
+ ' <div style="%tbt.">%loc!Set Cells To Sort!</div>'+
+ ' <select id="%id.sortlist" size="1" onfocus="%s.CmdGotFocus(this);"><option selected>[select range]</option></select>'+
+ ' <input type="button" value="%loc!OK!" onclick="%s.DoCmd(this, \'ok-setsort\');" style="font-size:x-small;">'+
+ ' </td>'+
+ ' <td style="vertical-align:middle;padding-right:16px;width:100px;text-align:right;">'+
+ ' <div style="%tbt.">&nbsp;</div>'+
+ ' <input type="button" id="%id.sortbutton" value="%loc!Sort Cells! A1:A1" onclick="%s.DoCmd(this, \'dosort\');" style="visibility:hidden;">'+
+ ' </td>'+
+ ' <td style="vertical-align:top;padding-right:16px;">'+
+ ' <table cellspacing="0" cellpadding="0"><tr>'+
+ ' <td style="vertical-align:top;">'+
+ ' <div style="%tbt.">%loc!Major Sort!</div>'+
+ ' <select id="%id.majorsort" size="1" onfocus="%s.CmdGotFocus(this);"></select>'+
+ ' </td><td>'+
+ ' <input type="radio" name="majorsort" id="%id.majorsortup" value="up" checked><span style="font-size:x-small;color:#FFF;">%loc!Up!</span><br>'+
+ ' <input type="radio" name="majorsort" id="%id.majorsortdown" value="down"><span style="font-size:x-small;color:#FFF;">%loc!Down!</span>'+
+ ' </td>'+
+ ' </tr></table>'+
+ ' </td>'+
+ ' <td style="vertical-align:top;padding-right:16px;">'+
+ ' <table cellspacing="0" cellpadding="0"><tr>'+
+ ' <td style="vertical-align:top;">'+
+ ' <div style="%tbt.">%loc!Minor Sort!</div>'+
+ ' <select id="%id.minorsort" size="1" onfocus="%s.CmdGotFocus(this);"></select>'+
+ ' </td><td>'+
+ ' <input type="radio" name="minorsort" id="%id.minorsortup" value="up" checked><span style="font-size:x-small;color:#FFF;">%loc!Up!</span><br>'+
+ ' <input type="radio" name="minorsort" id="%id.minorsortdown" value="down"><span style="font-size:x-small;color:#FFF;">%loc!Down!</span>'+
+ ' </td>'+
+ ' </tr></table>'+
+ ' </td>'+
+ ' <td style="vertical-align:top;padding-right:16px;">'+
+ ' <table cellspacing="0" cellpadding="0"><tr>'+
+ ' <td style="vertical-align:top;">'+
+ ' <div style="%tbt.">%loc!Last Sort!</div>'+
+ ' <select id="%id.lastsort" size="1" onfocus="%s.CmdGotFocus(this);"></select>'+
+ ' </td><td>'+
+ ' <input type="radio" name="lastsort" id="%id.lastsortup" value="up" checked><span style="font-size:x-small;color:#FFF;">%loc!Up!</span><br>'+
+ ' <input type="radio" name="lastsort" id="%id.lastsortdown" value="down"><span style="font-size:x-small;color:#FFF;">%loc!Down!</span>'+
+ ' </td>'+
+ ' </tr></table>'+
+ ' </td>'+
+ ' </tr></table>'+
+ ' </div>',
+ onclick: SocialCalc.SpreadsheetControlSortOnclick});
+ this.editor.SettingsCallbacks.sort = {save: SocialCalc.SpreadsheetControlSortSave, load: SocialCalc.SpreadsheetControlSortLoad};
+
+ // Audit
+
+ this.tabnums.audit = this.tabs.length;
+ this.tabs.push({name: "audit", text: "Audit", html:
+ '<div id="%id.audittools" style="display:none;">'+
+ ' <div style="%tbt.">&nbsp;</div>'+
+ '</div>',
+ view: "audit",
+ onclick:
+ function(s, t) {
+ var SCLoc = SocialCalc.LocalizeString;
+ var i, j;
+ var str = '<table cellspacing="0" cellpadding="0" style="margin-bottom:10px;"><tr><td style="font-size:small;padding:6px;"><b>'+SCLoc("Audit Trail This Session")+':</b><br><br>';
+ var stack = s.sheet.changes.stack;
+ var tos = s.sheet.changes.tos;
+ for (i=0; i<stack.length; i++) {
+ if (i==tos+1) str += '<br></td></tr><tr><td style="font-size:small;background-color:#EEE;padding:6px;">'+SCLoc("UNDONE STEPS")+':<br>';
+ for (j=0; j<stack[i].command.length; j++) {
+ str += SocialCalc.special_chars(stack[i].command[j]) + "<br>";
+ }
+ }
+ s.views.audit.element.innerHTML = str+"</td></tr></table>";
+ SocialCalc.CmdGotFocus(true);
+ },
+ onclickFocus: true
+ });
+
+ this.views["audit"] = {name: "audit",
+ divStyle: "border:1px solid black;overflow:auto;",
+ html: 'Audit Trail'
+ };
+
+ // Comment
+
+ this.tabnums.comment = this.tabs.length;
+ this.tabs.push({name: "comment", text: "Comment", html:
+ '<div id="%id.commenttools" style="display:none;">'+
+ '<table cellspacing="0" cellpadding="0"><tr><td>'+
+ '<textarea id="%id.commenttext" style="font-size:small;height:32px;width:600px;overflow:auto;" onfocus="%s.CmdGotFocus(this);"></textarea>'+
+ '</td><td style="vertical-align:top;">'+
+ '&nbsp;<input type="button" value="%loc!Save!" onclick="%s.SpreadsheetControlCommentSet();" style="font-size:x-small;">'+
+ '</td></tr></table>'+
+ '</div>',
+ view: "sheet",
+ onclick: SocialCalc.SpreadsheetControlCommentOnclick,
+ onunclick: SocialCalc.SpreadsheetControlCommentOnunclick
+ });
+
+ // Names
+
+ this.tabnums.names = this.tabs.length;
+ this.tabs.push({name: "names", text: "Names", html:
+ '<div id="%id.namestools" style="display:none;">'+
+ ' <table cellspacing="0" cellpadding="0"><tr>'+
+ ' <td style="vertical-align:top;padding-right:24px;">'+
+ ' <div style="%tbt.">%loc!Existing Names!</div>'+
+ ' <select id="%id.nameslist" size="1" onchange="%s.SpreadsheetControlNamesChangedName();" onfocus="%s.CmdGotFocus(this);"><option selected>[New]</option></select>'+
+ ' </td>'+
+ ' <td style="vertical-align:top;padding-right:6px;">'+
+ ' <div style="%tbt.">%loc!Name!</div>'+
+ ' <input type="text" id="%id.namesname" style="font-size:x-small;width:75px;" onfocus="%s.CmdGotFocus(this);">'+
+ ' </td>'+
+ ' <td style="vertical-align:top;padding-right:6px;">'+
+ ' <div style="%tbt.">%loc!Description!</div>'+
+ ' <input type="text" id="%id.namesdesc" style="font-size:x-small;width:150px;" onfocus="%s.CmdGotFocus(this);">'+
+ ' </td>'+
+ ' <td style="vertical-align:top;padding-right:6px;">'+
+ ' <div style="%tbt.">%loc!Value!</div>'+
+ ' <input type="text" id="%id.namesvalue" width="16" style="font-size:x-small;width:100px;" onfocus="%s.CmdGotFocus(this);">'+
+ ' </td>'+
+ ' <td style="vertical-align:top;padding-right:12px;width:100px;">'+
+ ' <div style="%tbt.">%loc!Set Value To!</div>'+
+ ' <input type="button" id="%id.namesrangeproposal" value="A1" onclick="%s.SpreadsheetControlNamesSetValue();" style="font-size:x-small;">'+
+ ' </td>'+
+ ' <td style="vertical-align:top;padding-right:6px;">'+
+ ' <div style="%tbt.">&nbsp;</div>'+
+ ' <input type="button" value="%loc!Save!" onclick="%s.SpreadsheetControlNamesSave();" style="font-size:x-small;">'+
+ ' <input type="button" value="%loc!Delete!" onclick="%s.SpreadsheetControlNamesDelete()" style="font-size:x-small;">'+
+ ' </td>'+
+ ' </tr></table>'+
+ '</div>',
+ view: "sheet",
+ onclick: SocialCalc.SpreadsheetControlNamesOnclick,
+ onunclick: SocialCalc.SpreadsheetControlNamesOnunclick
+ });
+
+ // Clipboard
+
+ this.tabnums.clipboard = this.tabs.length;
+ this.tabs.push({name: "clipboard", text: "Clipboard", html:
+ '<div id="%id.clipboardtools" style="display:none;">'+
+ ' <table cellspacing="0" cellpadding="0"><tr>'+
+ ' <td style="vertical-align:top;padding-right:24px;">'+
+ ' <div style="%tbt.">'+
+ ' &nbsp;'+
+ ' </div>'+
+ ' </td>'+
+ ' </tr></table>'+
+ '</div>',
+ view: "clipboard",
+ onclick: SocialCalc.SpreadsheetControlClipboardOnclick,
+ onclickFocus: "clipboardtext"
+ });
+
+ this.views["clipboard"] = {name: "clipboard", divStyle: "overflow:auto;", html:
+ ' <div style="font-size:x-small;padding:5px 0px 10px 0px;">'+
+ ' <b>%loc!Display Clipboard in!:</b>'+
+ ' <input type="radio" id="%id.clipboardformat-tab" name="%id.clipboardformat" checked onclick="%s.SpreadsheetControlClipboardFormat(\'tab\');"> %loc!Tab-delimited format! &nbsp;'+
+ ' <input type="radio" id="%id.clipboardformat-csv" name="%id.clipboardformat" onclick="%s.SpreadsheetControlClipboardFormat(\'csv\');"> %loc!CSV format! &nbsp;'+
+ ' <input type="radio" id="%id.clipboardformat-scsave" name="%id.clipboardformat" onclick="%s.SpreadsheetControlClipboardFormat(\'scsave\');"> %loc!SocialCalc-save format!'+
+ ' </div>'+
+ ' <input type="button" value="%loc!Load SocialCalc Clipboard With This!" style="font-size:x-small;" onclick="%s.SpreadsheetControlClipboardLoad();">&nbsp; '+
+ ' <input type="button" value="%loc!Clear SocialCalc Clipboard!" style="font-size:x-small;" onclick="%s.SpreadsheetControlClipboardClear();">&nbsp; '+
+ ' <br>'+
+ ' <textarea id="%id.clipboardtext" style="font-size:small;height:350px;width:800px;overflow:auto;" onfocus="%s.CmdGotFocus(this);"></textarea>'
+ };
+
+ return;
+
+ }
+
+// Methods:
+
+SocialCalc.SpreadsheetControl.prototype.InitializeSpreadsheetControl =
+ function(node, height, width, spacebelow) {return SocialCalc.InitializeSpreadsheetControl(this, node, height, width, spacebelow);};
+SocialCalc.SpreadsheetControl.prototype.DoOnResize = function() {return SocialCalc.DoOnResize(this);};
+SocialCalc.SpreadsheetControl.prototype.SizeSSDiv = function() {return SocialCalc.SizeSSDiv(this);};
+SocialCalc.SpreadsheetControl.prototype.ExecuteCommand =
+ function(combostr, sstr) {return SocialCalc.SpreadsheetControlExecuteCommand(this, combostr, sstr);};
+SocialCalc.SpreadsheetControl.prototype.CreateSheetHTML =
+ function() {return SocialCalc.SpreadsheetControlCreateSheetHTML(this);};
+SocialCalc.SpreadsheetControl.prototype.CreateSpreadsheetSave =
+ function() {return SocialCalc.SpreadsheetControlCreateSpreadsheetSave(this);};
+SocialCalc.SpreadsheetControl.prototype.DecodeSpreadsheetSave =
+ function(str) {return SocialCalc.SpreadsheetControlDecodeSpreadsheetSave(this, str);};
+SocialCalc.SpreadsheetControl.prototype.CreateCellHTML =
+ function(coord) {return SocialCalc.SpreadsheetControlCreateCellHTML(this, coord);};
+SocialCalc.SpreadsheetControl.prototype.CreateCellHTMLSave =
+ function(range) {return SocialCalc.SpreadsheetControlCreateCellHTMLSave(this, range);};
+
+
+// Sheet Methods to make things a little easier:
+
+SocialCalc.SpreadsheetControl.prototype.ParseSheetSave = function(str) {return this.sheet.ParseSheetSave(str);};
+SocialCalc.SpreadsheetControl.prototype.CreateSheetSave = function() {return this.sheet.CreateSheetSave();};
+
+
+// Functions:
+
+//
+// InitializeSpreadsheetControl(spreadsheet, node, height, width, spacebelow)
+//
+// Creates the control elements and makes them the child of node (string or element).
+// If present, height and width specify size.
+// If either is 0 or null (missing), the maximum that fits on the screen
+// (taking spacebelow into account) is used.
+//
+// Displays the tabs and creates the views (other than "sheet").
+// The first tab is set as selected, but onclick is not invoked.
+//
+// You should do a redisplay or recalc (which redisplays) after running this.
+//
+
+SocialCalc.InitializeSpreadsheetControl = function(spreadsheet, node, height, width, spacebelow) {
+
+ var scc = SocialCalc.Constants;
+ var SCLoc = SocialCalc.LocalizeString;
+ var SCLocSS = SocialCalc.LocalizeSubstrings;
+
+ var html, child, i, vname, v, style, button, bele;
+ var tabs = spreadsheet.tabs;
+ var views = spreadsheet.views;
+
+ spreadsheet.requestedHeight = height;
+ spreadsheet.requestedWidth = width;
+ spreadsheet.requestedSpaceBelow = spacebelow;
+
+ if (typeof node == "string") node = document.getElementById(node);
+
+ if (node == null) {
+ alert("SocialCalc.SpreadsheetControl not given parent node.");
+ }
+
+ spreadsheet.parentNode = node;
+
+ // create node to hold spreadsheet control
+
+ spreadsheet.spreadsheetDiv = document.createElement("div");
+
+ spreadsheet.SizeSSDiv(); // calculate and fill in the size values
+
+ for (child=node.firstChild; child!=null; child=node.firstChild) {
+ node.removeChild(child);
+ }
+
+ // create the tabbed UI at the top
+
+ html = '<div><div style="'+spreadsheet.toolbarbackground+'padding:12px 10px 10px 4px;height:40px;">';
+
+ for (i=0; i<tabs.length; i++) {
+ html += tabs[i].html;
+ }
+
+ html += '</div>'+
+ '<div style="'+spreadsheet.tabbackground+'padding-bottom:4px;margin:0px 0px 8px 0px;">'+
+ '<table cellpadding="0" cellspacing="0"><tr>';
+
+ for (i=0; i<tabs.length; i++) {
+ html += ' <td id="%id.' + tabs[i].name + 'tab" style="' +
+ (i==0 ? spreadsheet.tabselectedCSS : spreadsheet.tabplainCSS) +
+ '" onclick="%s.SetTab(this);">' + SCLoc(tabs[i].text) + '</td>';
+ }
+
+ html += ' </tr></table></div></div>';
+
+ spreadsheet.currentTab = 0; // this is where we started
+
+ for (style in spreadsheet.tabreplacements) {
+ html = html.replace(spreadsheet.tabreplacements[style].regex, spreadsheet.tabreplacements[style].replacement);
+ }
+ html = html.replace(/\%s\./g, "SocialCalc.");
+ html = html.replace(/\%id\./g, spreadsheet.idPrefix);
+ html = html.replace(/\%tbt\./g, spreadsheet.toolbartext);
+ html = html.replace(/\%img\./g, spreadsheet.imagePrefix);
+
+ html = SCLocSS(html); // localize with %loc!string! and %scc!constant!
+
+ spreadsheet.spreadsheetDiv.innerHTML = html;
+
+ node.appendChild(spreadsheet.spreadsheetDiv);
+
+ // Initialize SocialCalc buttons
+
+spreadsheet.Buttons = {
+ button_undo: {tooltip: "Undo", command: "undo"},
+ button_redo: {tooltip: "Redo", command: "redo"},
+ button_copy: {tooltip: "Copy", command: "copy"},
+ button_cut: {tooltip: "Cut", command: "cut"},
+ button_paste: {tooltip: "Paste", command: "paste"},
+ button_pasteformats: {tooltip: "Paste Formats", command: "pasteformats"},
+ button_delete: {tooltip: "Delete Contents", command: "delete"},
+ button_filldown: {tooltip: "Fill Down", command: "filldown"},
+ button_fillright: {tooltip: "Fill Right", command: "fillright"},
+ button_movefrom: {tooltip: "Set/Clear Move From", command: "movefrom"},
+ button_movepaste: {tooltip: "Move Paste", command: "movepaste"},
+ button_moveinsert: {tooltip: "Move Insert", command: "moveinsert"},
+ button_alignleft: {tooltip: "Align Left", command: "align-left"},
+ button_aligncenter: {tooltip: "Align Center", command: "align-center"},
+ button_alignright: {tooltip: "Align Right", command: "align-right"},
+ button_borderon: {tooltip: "Borders On", command: "borderon"},
+ button_borderoff: {tooltip: "Borders Off", command: "borderoff"},
+ button_swapcolors: {tooltip: "Swap Colors", command: "swapcolors"},
+ button_merge: {tooltip: "Merge Cells", command: "merge"},
+ button_unmerge: {tooltip: "Unmerge Cells", command: "unmerge"},
+ button_insertrow: {tooltip: "Insert Row", command: "insertrow"},
+ button_insertcol: {tooltip: "Insert Column", command: "insertcol"},
+ button_deleterow: {tooltip: "Delete Row", command: "deleterow"},
+ button_deletecol: {tooltip: "Delete Column", command: "deletecol"},
+ button_recalc: {tooltip: "Recalc", command: "recalc"}
+ }
+
+ for (button in spreadsheet.Buttons) {
+ bele = document.getElementById(spreadsheet.idPrefix+button);
+ if (!bele) {alert("Button "+(spreadsheet.idPrefix+button)+" missing"); continue;}
+ bele.style.border = "1px solid "+scc.ISCButtonBorderNormal;
+ SocialCalc.TooltipRegister(bele, SCLoc(spreadsheet.Buttons[button].tooltip), {});
+ SocialCalc.ButtonRegister(bele,
+ {normalstyle: "border:1px solid "+scc.ISCButtonBorderNormal+";backgroundColor:"+scc.ISCButtonBorderNormal+";",
+ hoverstyle: "border:1px solid "+scc.ISCButtonBorderHover+";backgroundColor:"+scc.ISCButtonBorderNormal+";",
+ downstyle: "border:1px solid "+scc.ISCButtonBorderDown+";backgroundColor:"+scc.ISCButtonDownBackground+";"},
+ {MouseDown: SocialCalc.DoButtonCmd, command: spreadsheet.Buttons[button].command});
+ }
+
+ // create formula bar
+
+ spreadsheet.formulabarDiv = document.createElement("div");
+ spreadsheet.formulabarDiv.style.height = spreadsheet.formulabarheight + "px";
+ spreadsheet.formulabarDiv.innerHTML = '<input type="text" size="60" value="">&nbsp;'; //'<textarea rows="4" cols="60" style="z-index:5;background-color:white;position:relative;"></textarea>&nbsp;';
+ spreadsheet.spreadsheetDiv.appendChild(spreadsheet.formulabarDiv);
+ var inputbox = new SocialCalc.InputBox(spreadsheet.formulabarDiv.firstChild, spreadsheet.editor);
+
+ for (button in spreadsheet.formulabuttons) {
+ bele = document.createElement("img");
+ bele.id = spreadsheet.idPrefix+button;
+ bele.src = spreadsheet.imagePrefix+spreadsheet.formulabuttons[button].image;
+ bele.style.verticalAlign = "middle";
+ bele.style.border = "1px solid #FFF";
+ bele.style.marginLeft = "4px";
+ SocialCalc.TooltipRegister(bele, SCLoc(spreadsheet.formulabuttons[button].tooltip), {});
+ SocialCalc.ButtonRegister(bele,
+ {normalstyle: "border:1px solid #FFF;backgroundColor:#FFF;",
+ hoverstyle: "border:1px solid #CCC;backgroundColor:#FFF;",
+ downstyle: "border:1px solid #000;backgroundColor:#FFF;"},
+ {MouseDown: spreadsheet.formulabuttons[button].command});
+ spreadsheet.formulabarDiv.appendChild(bele);
+ }
+
+ // initialize tabs that need it
+
+ for (i=0; i<tabs.length; i++) { // execute any tab-specific initialization code
+ if (tabs[i].oncreate) {
+ tabs[i].oncreate(spreadsheet, tabs[i].name);
+ }
+ }
+
+ // create sheet view and others
+
+ spreadsheet.nonviewheight = spreadsheet.statuslineheight +
+ spreadsheet.spreadsheetDiv.firstChild.offsetHeight +
+ spreadsheet.spreadsheetDiv.lastChild.offsetHeight;
+ spreadsheet.viewheight = spreadsheet.height-spreadsheet.nonviewheight;
+ spreadsheet.editorDiv=spreadsheet.editor.CreateTableEditor(spreadsheet.width, spreadsheet.viewheight);
+
+ spreadsheet.spreadsheetDiv.appendChild(spreadsheet.editorDiv);
+
+ for (vname in views) {
+ html = views[vname].html;
+ for (style in views[vname].replacements) {
+ html = html.replace(views[vname].replacements[style].regex, views[vname].replacements[style].replacement);
+ }
+ html = html.replace(/\%s\./g, "SocialCalc.");
+ html = html.replace(/\%id\./g, spreadsheet.idPrefix);
+ html = html.replace(/\%tbt\./g, spreadsheet.toolbartext);
+ html = html.replace(/\%img\./g, spreadsheet.imagePrefix);
+ v = document.createElement("div");
+ SocialCalc.setStyles(v, views[vname].divStyle);
+ v.style.display = "none";
+ v.style.width = spreadsheet.width + "px";
+ v.style.height = spreadsheet.viewheight + "px";
+
+ html = SCLocSS(html); // localize with %loc!string!, etc.
+
+ v.innerHTML = html;
+ spreadsheet.spreadsheetDiv.appendChild(v);
+ views[vname].element = v;
+ if (views[vname].oncreate) {
+ views[vname].oncreate(spreadsheet, views[vname]);
+ }
+ }
+
+ views.sheet = {name: "sheet", element: spreadsheet.editorDiv};
+
+ // create statusline
+
+ spreadsheet.statuslineDiv = document.createElement("div");
+ spreadsheet.statuslineDiv.style.cssText = spreadsheet.statuslineCSS;
+ spreadsheet.statuslineDiv.style.height = spreadsheet.statuslineheight + "px";
+ spreadsheet.statuslineDiv.id = spreadsheet.idPrefix+"statusline";
+ spreadsheet.spreadsheetDiv.appendChild(spreadsheet.statuslineDiv);
+
+ // done - refresh screen needed
+
+ return;
+
+ }
+
+//
+// outstr = SocialCalc.LocalizeString(str)
+//
+// SocialCalc function to make localization easier.
+// If str is "Text to localize", it returns
+// SocialCalc.Constants.s_loc_text_to_localize if
+// it exists, or else with just "Text to localize".
+// Note that spaces are replaced with "_" and other special
+// chars with "X" in the name of the constant (e.g., "A & B"
+// would look for SocialCalc.Constants.s_loc_a_X_b.
+//
+
+SocialCalc.LocalizeString = function(str) {
+ var cstr = SocialCalc.LocalizeStringList[str]; // found already this session?
+ if (1) { // no - look up
+ //localization note: right now this if is changed from !cstr to 1 so that the effect is reflected properly, might be required to change it over the
+ // time for effieciency but for now, it's fine.....
+ cstr = SocialCalc.Constants["s_loc_"+str.toLowerCase().replace(/\s/g, "_").replace(/\W/g, "X")] || str;
+ SocialCalc.LocalizeStringList[str] = cstr;
+ }
+ //SocialCalc.Constants.s_MainHelpText= SocialCalc.Constants.s_MainHelpText+' string returned is '+cstr+', ';
+ return cstr;
+ }
+
+SocialCalc.LocalizeStringList = {}; // a list of strings to localize accumulated by the routine
+
+//
+// outstr = SocialCalc.LocalizeSubstrings(str)
+//
+// SocialCalc function to make localization easier using %loc and %scc.
+//
+// Replaces sections of str with:
+// %loc!Text to localize!
+// with SocialCalc.Constants.s_loc_text_to_localize if
+// it exists, or else with just "Text to localize".
+// Note that spaces are replaced with "_" and other special
+// chars with "X" in the name of the constant (e.g., %loc!A & B!
+// would look for SocialCalc.Constants.s_loc_a_X_b.
+// Uses SocialCalc.LocalizeString for this.
+//
+// Replaces sections of str with:
+// %ssc!constant-name!
+// with SocialCalc.Constants.constant-name.
+// If the constant doesn't exist, throws and alert.
+//
+
+SocialCalc.LocalizeSubstrings = function(str) {
+
+ var SCLoc = SocialCalc.LocalizeString;
+
+ return str.replace(/%(loc|ssc)!(.*?)!/g, function(a, t, c) {
+ if (t=="ssc") {
+ return SocialCalc.Constants[c] || alert("Missing constant: "+c);
+ }
+ else {
+ return SCLoc(c);
+ }
+ });
+
+ }
+
+//
+// obj = GetSpreadsheetControlObject()
+//
+// Returns the current spreadsheet control object
+//
+
+SocialCalc.GetSpreadsheetControlObject = function() {
+
+ var csco = SocialCalc.CurrentSpreadsheetControlObject;
+ if (csco) return csco;
+
+ throw ("No current SpreadsheetControl object.");
+
+ }
+
+
+//
+// SocialCalc.DoOnResize(spreadsheet)
+//
+// Processes an onResize event, setting the different views.
+//
+
+SocialCalc.DoOnResize = function(spreadsheet) {
+
+ var v;
+ var views = spreadsheet.views;
+
+ var needresize = spreadsheet.SizeSSDiv();
+ if (!needresize) return;
+
+ for (vname in views) {
+ v = views[vname].element;
+ v.style.width = spreadsheet.width + "px";
+ v.style.height = (spreadsheet.height-spreadsheet.nonviewheight) + "px";
+ }
+
+ spreadsheet.editor.ResizeTableEditor(spreadsheet.width, spreadsheet.height-spreadsheet.nonviewheight);
+
+ }
+
+
+//
+// resized = SocialCalc.SizeSSDiv(spreadsheet)
+//
+// Figures out a reasonable size for the spreadsheet, given any requested values and viewport.
+// Sets ssdiv to that.
+// Return true if different than existing values.
+//
+
+SocialCalc.SizeSSDiv = function(spreadsheet) {
+
+ var sizes, pos, resized, nodestyle, newval;
+ var fudgefactorX = 10; // for IE
+ var fudgefactorY = 10;
+
+ resized = false;
+
+ sizes = SocialCalc.GetViewportInfo();
+ pos = SocialCalc.GetElementPosition(spreadsheet.parentNode);
+ pos.bottom = 0;
+ pos.right = 0;
+
+ nodestyle = spreadsheet.parentNode.style;
+
+ if (nodestyle.marginTop) {
+ pos.top += nodestyle.marginTop.slice(0,-2)-0;
+ }
+ if (nodestyle.marginBottom) {
+ pos.bottom += nodestyle.marginBottom.slice(0,-2)-0;
+ }
+ if (nodestyle.marginLeft) {
+ pos.left += nodestyle.marginLeft.slice(0,-2)-0;
+ }
+ if (nodestyle.marginRight) {
+ pos.right += nodestyle.marginRight.slice(0,-2)-0;
+ }
+
+ newval = spreadsheet.requestedHeight ||
+ sizes.height - (pos.top + pos.bottom + fudgefactorY) -
+ (spreadsheet.requestedSpaceBelow || 0);
+ if (spreadsheet.height != newval) {
+ spreadsheet.height = newval;
+ spreadsheet.spreadsheetDiv.style.height = newval + "px";
+ resized = true;
+ }
+ newval = spreadsheet.requestedWidth ||
+ sizes.width - (pos.left + pos.right + fudgefactorX) || 700;
+ if (spreadsheet.width != newval) {
+ spreadsheet.width = newval;
+ spreadsheet.spreadsheetDiv.style.width = newval + "px";
+ resized = true;
+ }
+
+ return resized;
+
+ }
+
+
+//
+// SocialCalc.SetTab(obj)
+//
+// The obj argument is either a string with the tab name or a DOM element with an ID
+//
+
+SocialCalc.SetTab = function(obj) {
+
+ var newtab, tname, newtabnum, newview, i, vname, ele;
+ var menutabs = {};
+ var tools = {};
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var tabs = spreadsheet.tabs;
+ var views = spreadsheet.views;
+
+ if (typeof obj == "string") {
+ newtab = obj;
+ }
+ else {
+ newtab = obj.id.slice(spreadsheet.idPrefix.length,-3);
+ }
+
+ if (spreadsheet.editor.busy && // if busy and switching from "sheet", ignore
+ (!tabs[spreadsheet.currentTab].view || tabs[spreadsheet.currentTab].view=="sheet")) {
+ for (i=0; i<tabs.length; i++) {
+ if(tabs[i].name==newtab && (tabs[i].view && tabs[i].view!="sheet")) {
+ return;
+ }
+ }
+ }
+
+ if (spreadsheet.tabs[spreadsheet.currentTab].onunclick) {
+ spreadsheet.tabs[spreadsheet.currentTab].onunclick(spreadsheet, spreadsheet.tabs[spreadsheet.currentTab].name);
+ }
+
+ for (i=0; i<tabs.length; i++) {
+ tname = tabs[i].name;
+ menutabs[tname] = document.getElementById(spreadsheet.idPrefix+tname+"tab");
+ tools[tname] = document.getElementById(spreadsheet.idPrefix+tname+"tools");
+ if (tname==newtab) {
+ newtabnum = i;
+ tools[tname].style.display = "block";
+ menutabs[tname].style.cssText = spreadsheet.tabselectedCSS;
+ }
+ else {
+ tools[tname].style.display = "none";
+ menutabs[tname].style.cssText = spreadsheet.tabplainCSS;
+ }
+ }
+
+ spreadsheet.currentTab = newtabnum;
+
+ if (tabs[newtabnum].onclick) {
+ tabs[newtabnum].onclick(spreadsheet, newtab);
+ }
+
+ for (vname in views) {
+ if ((!tabs[newtabnum].view && vname == "sheet") || tabs[newtabnum].view == vname) {
+ views[vname].element.style.display = "block";
+ newview = vname;
+ }
+ else {
+ views[vname].element.style.display = "none";
+ }
+ }
+
+ if (tabs[newtabnum].onclickFocus) {
+ ele = tabs[newtabnum].onclickFocus;
+ if (typeof ele == "string") {
+ ele = document.getElementById(spreadsheet.idPrefix+ele);
+ ele.focus();
+ }
+ SocialCalc.CmdGotFocus(ele);
+ }
+ else {
+ SocialCalc.KeyboardFocus();
+ }
+
+ if (views[newview].needsresize && views[newview].onresize) {
+ views[newview].needsresize = false;
+ views[newview].onresize(spreadsheet, views[newview]);
+ }
+
+ if (newview == "sheet") {
+ spreadsheet.statuslineDiv.style.display = "block";
+ spreadsheet.editor.ScheduleRender();
+ }
+ else {
+ spreadsheet.statuslineDiv.style.display = "none";
+ }
+
+ return;
+
+ }
+
+//
+// SocialCalc.SpreadsheetControlStatuslineCallback
+//
+
+SocialCalc.SpreadsheetControlStatuslineCallback = function(editor, status, arg, params) {
+
+ var rele1, rele2;
+
+ var ele = document.getElementById(params.statuslineid);
+
+ if (ele) {
+ ele.innerHTML = editor.GetStatuslineString(status, arg, params);
+ }
+
+ switch (status) {
+ case "cmdendnorender":
+ case "calcfinished":
+ case "doneposcalc":
+ rele1 = document.getElementById(params.recalcid1);
+ rele2 = document.getElementById(params.recalcid2);
+ if (!rele1 || !rele2) break;
+ if (editor.context.sheetobj.attribs.needsrecalc=="yes") {
+ rele1.style.display = "inline";
+ rele2.style.display = "inline";
+ }
+ else {
+ rele1.style.display = "none";
+ rele2.style.display = "none";
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ }
+
+
+//
+// SocialCalc.UpdateSortRangeProposal(editor)
+//
+// Updates sort range proposed in the UI in element idPrefix+sortlist
+//
+
+SocialCalc.UpdateSortRangeProposal = function(editor) {
+
+ var ele = document.getElementById(SocialCalc.GetSpreadsheetControlObject().idPrefix+"sortlist");
+ if (editor.range.hasrange) {
+ ele.options[0].text = SocialCalc.crToCoord(editor.range.left, editor.range.top) + ":" +
+ SocialCalc.crToCoord(editor.range.right, editor.range.bottom);
+ }
+ else {
+ ele.options[0].text = SocialCalc.LocalizeString("[select range]");
+ }
+
+ }
+
+//
+// SocialCalc.LoadColumnChoosers(spreadsheet)
+//
+// Updates list of columns for choosing which to sort for Major, Minor, and Last sort
+//
+
+SocialCalc.LoadColumnChoosers = function(spreadsheet) {
+
+ var SCLoc = SocialCalc.LocalizeString;
+
+ var sortrange, nrange, rparts, col, colname, sele, oldindex;
+
+ if (spreadsheet.sortrange && spreadsheet.sortrange.indexOf(":")==-1) { // sortrange is a named range
+ nrange = SocialCalc.Formula.LookupName(spreadsheet.sheet, spreadsheet.sortrange || "");
+ if (nrange.type == "range") {
+ rparts = nrange.value.match(/^(.*)\|(.*)\|$/);
+ sortrange = rparts[1] + ":" + rparts[2];
+ }
+ else {
+ sortrange = "A1:A1";
+ }
+ }
+ else {
+ sortrange = spreadsheet.sortrange;
+ }
+ var range = SocialCalc.ParseRange(sortrange);
+ sele = document.getElementById(spreadsheet.idPrefix+"majorsort");
+ oldindex = sele.selectedIndex;
+ sele.options.length = 0;
+ sele.options[sele.options.length] = new Option(SCLoc("[None]"), "");
+ for (var col=range.cr1.col; col<=range.cr2.col; col++) {
+ colname = SocialCalc.rcColname(col);
+ sele.options[sele.options.length] = new Option(SCLoc("Column ")+colname, colname);
+ }
+ sele.selectedIndex = oldindex > 1 && oldindex <= (range.cr2.col-range.cr1.col+1) ? oldindex : 1; // restore what was there if reasonable
+ sele = document.getElementById(spreadsheet.idPrefix+"minorsort");
+ oldindex = sele.selectedIndex;
+ sele.options.length = 0;
+ sele.options[sele.options.length] = new Option(SCLoc("[None]"), "");
+ for (var col=range.cr1.col; col<=range.cr2.col; col++) {
+ colname = SocialCalc.rcColname(col);
+ sele.options[sele.options.length] = new Option(colname, colname);
+ }
+ sele.selectedIndex = oldindex > 0 && oldindex <= (range.cr2.col-range.cr1.col+1) ? oldindex : 0; // default to [none]
+ sele = document.getElementById(spreadsheet.idPrefix+"lastsort");
+ oldindex = sele.selectedIndex;
+ sele.options.length = 0;
+ sele.options[sele.options.length] = new Option(SCLoc("[None]"), "");
+ for (var col=range.cr1.col; col<=range.cr2.col; col++) {
+ colname = SocialCalc.rcColname(col);
+ sele.options[sele.options.length] = new Option(colname, colname);
+ }
+ sele.selectedIndex = oldindex > 0 && oldindex <= (range.cr2.col-range.cr1.col+1) ? oldindex : 0; // default to [none]
+
+ }
+
+//
+// SocialCalc.CmdGotFocus(obj)
+//
+// Sets SocialCalc.Keyboard.passThru: obj should be element with focus or "true"
+//
+
+SocialCalc.CmdGotFocus = function(obj) {
+
+ SocialCalc.Keyboard.passThru = obj;
+
+ }
+
+
+//
+// SocialCalc.DoButtonCmd(e, buttoninfo, bobj)
+//
+
+SocialCalc.DoButtonCmd = function(e, buttoninfo, bobj) {
+
+ SocialCalc.DoCmd(bobj.element, bobj.functionobj.command);
+
+ }
+
+//
+// SocialCalc.DoCmd(obj, which)
+//
+// xxx
+//
+
+SocialCalc.DoCmd = function(obj, which) {
+
+ var combostr, sstr, cl, i, clele, slist, slistele, str, sele, rele, lele, ele, sortrange, nrange, rparts;
+ var sheet, cell, color, bgcolor, defaultcolor, defaultbgcolor;
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var editor = spreadsheet.editor;
+
+ switch (which) {
+ case "undo":
+ spreadsheet.ExecuteCommand("undo", "");
+ break;
+
+ case "redo":
+ spreadsheet.ExecuteCommand("redo", "");
+ break;
+
+ case "fill-rowcolstuff":
+ case "fill-text":
+ cl = which.substring(5);
+ clele = document.getElementById(spreadsheet.idPrefix+cl+"list");
+ clele.length = 0;
+ for (i=0; i<SocialCalc.SpreadsheetCmdTable[cl].length; i++) {
+ clele.options[i] = new Option(SocialCalc.SpreadsheetCmdTable[cl][i].t);
+ }
+ which = "changed-"+cl; // fall through to changed code
+
+ case "changed-rowcolstuff":
+ case "changed-text":
+ cl = which.substring(8);
+ clele = document.getElementById(spreadsheet.idPrefix+cl+"list");
+ slist = SocialCalc.SpreadsheetCmdTable.slists[SocialCalc.SpreadsheetCmdTable[cl][clele.selectedIndex].s]; // get sList for this command
+ slistele = document.getElementById(spreadsheet.idPrefix+cl+"slist");
+ slistele.length = 0; // reset
+ for (i=0; i<(slist.length||0); i++) {
+ slistele.options[i] = new Option(slist[i].t, slist[i].s);
+ }
+ return; // nothing else to do
+
+ case "ok-rowcolstuff":
+ case "ok-text":
+ cl = which.substring(3);
+ clele = document.getElementById(spreadsheet.idPrefix+cl+"list");
+ slistele = document.getElementById(spreadsheet.idPrefix+cl+"slist");
+ combostr = SocialCalc.SpreadsheetCmdTable[cl][clele.selectedIndex].c;
+ sstr = slistele[slistele.selectedIndex].value;
+ SocialCalc.SpreadsheetControlExecuteCommand(obj, combostr, sstr);
+ break;
+
+ case "ok-setsort":
+ lele = document.getElementById(spreadsheet.idPrefix+"sortlist");
+ if (lele.selectedIndex==0) {
+ if (editor.range.hasrange) {
+ spreadsheet.sortrange = SocialCalc.crToCoord(editor.range.left, editor.range.top) + ":" +
+ SocialCalc.crToCoord(editor.range.right, editor.range.bottom);
+ }
+ else {
+ spreadsheet.sortrange = editor.ecell.coord+":"+editor.ecell.coord;
+ }
+ }
+ else {
+ spreadsheet.sortrange = lele.options[lele.selectedIndex].value;
+ }
+ ele = document.getElementById(spreadsheet.idPrefix+"sortbutton");
+ ele.value = SocialCalc.LocalizeString("Sort ")+spreadsheet.sortrange;
+ ele.style.visibility = "visible";
+ SocialCalc.LoadColumnChoosers(spreadsheet);
+ if (obj && obj.blur) obj.blur();
+ SocialCalc.KeyboardFocus();
+ return;
+
+ case "dosort":
+ if (spreadsheet.sortrange && spreadsheet.sortrange.indexOf(":")==-1) { // sortrange is a named range
+ nrange = SocialCalc.Formula.LookupName(spreadsheet.sheet, spreadsheet.sortrange || "");
+ if (nrange.type != "range") return;
+ rparts = nrange.value.match(/^(.*)\|(.*)\|$/);
+ sortrange = rparts[1] + ":" + rparts[2];
+ }
+ else {
+ sortrange = spreadsheet.sortrange;
+ }
+ if (sortrange == "A1:A1") return;
+ str = "sort "+sortrange+" ";
+ sele = document.getElementById(spreadsheet.idPrefix+"majorsort");
+ rele = document.getElementById(spreadsheet.idPrefix+"majorsortup");
+ str += sele.options[sele.selectedIndex].value + (rele.checked ? " up" : " down");
+ sele = document.getElementById(spreadsheet.idPrefix+"minorsort");
+ if (sele.selectedIndex>0) {
+ rele = document.getElementById(spreadsheet.idPrefix+"minorsortup");
+ str += " "+sele.options[sele.selectedIndex].value + (rele.checked ? " up" : " down");
+ }
+ sele = document.getElementById(spreadsheet.idPrefix+"lastsort");
+ if (sele.selectedIndex>0) {
+ rele = document.getElementById(spreadsheet.idPrefix+"lastsortup");
+ str += " "+sele.options[sele.selectedIndex].value + (rele.checked ? " up" : " down");
+ }
+ spreadsheet.ExecuteCommand(str, "");
+ break;
+
+ case "merge":
+ combostr = SocialCalc.SpreadsheetCmdLookup[which] || "";
+ sstr = SocialCalc.SpreadsheetCmdSLookup[which] || "";
+ spreadsheet.ExecuteCommand(combostr, sstr);
+ if (editor.range.hasrange) { // set ecell to upper left
+ editor.MoveECell(SocialCalc.crToCoord(editor.range.left, editor.range.top));
+ editor.RangeRemove();
+ }
+ break;
+
+ case "movefrom":
+ if (editor.range2.hasrange) { // toggle if already there
+ spreadsheet.context.cursorsuffix = "";
+ editor.Range2Remove();
+ spreadsheet.ExecuteCommand("redisplay", "");
+ }
+ else if (editor.range.hasrange) { // set range2 to range or one cell
+ editor.range2.top = editor.range.top;
+ editor.range2.right = editor.range.right;
+ editor.range2.bottom = editor.range.bottom;
+ editor.range2.left = editor.range.left;
+ editor.range2.hasrange = true;
+ editor.MoveECell(SocialCalc.crToCoord(editor.range.left, editor.range.top));
+ }
+ else {
+ editor.range2.top = editor.ecell.row;
+ editor.range2.right = editor.ecell.col;
+ editor.range2.bottom = editor.ecell.row;
+ editor.range2.left = editor.ecell.col;
+ editor.range2.hasrange = true;
+ }
+ str = editor.range2.hasrange ? "" : "off";
+ ele = document.getElementById(spreadsheet.idPrefix+"button_movefrom");
+ ele.src=spreadsheet.imagePrefix+"movefrom"+str+".gif";
+ ele = document.getElementById(spreadsheet.idPrefix+"button_movepaste");
+ ele.src=spreadsheet.imagePrefix+"movepaste"+str+".gif";
+ ele = document.getElementById(spreadsheet.idPrefix+"button_moveinsert");
+ ele.src=spreadsheet.imagePrefix+"moveinsert"+str+".gif";
+ if (editor.range2.hasrange) editor.RangeRemove();
+ break;
+
+ case "movepaste":
+ case "moveinsert":
+ if (editor.range2.hasrange) {
+ spreadsheet.context.cursorsuffix = "";
+ combostr = which+" "+
+ SocialCalc.crToCoord(editor.range2.left, editor.range2.top) + ":" +
+ SocialCalc.crToCoord(editor.range2.right, editor.range2.bottom)
+ +" "+editor.ecell.coord;
+ spreadsheet.ExecuteCommand(combostr, "");
+ editor.Range2Remove();
+ ele = document.getElementById(spreadsheet.idPrefix+"button_movefrom");
+ ele.src=spreadsheet.imagePrefix+"movefromoff.gif";
+ ele = document.getElementById(spreadsheet.idPrefix+"button_movepaste");
+ ele.src=spreadsheet.imagePrefix+"movepasteoff.gif";
+ ele = document.getElementById(spreadsheet.idPrefix+"button_moveinsert");
+ ele.src=spreadsheet.imagePrefix+"moveinsertoff.gif";
+ }
+ break;
+
+ case "swapcolors":
+ sheet = spreadsheet.sheet;
+ cell = sheet.GetAssuredCell(editor.ecell.coord);
+ defaultcolor = sheet.attribs.defaultcolor ? sheet.colors[sheet.attribs.defaultcolor] : "rgb(0,0,0)";
+ defaultbgcolor = sheet.attribs.defaultbgcolor ? sheet.colors[sheet.attribs.defaultbgcolor] : "rgb(255,255,255)";
+ color = cell.color ? sheet.colors[cell.color] : defaultcolor; // get color
+ if (color == defaultbgcolor) color = ""; // going to swap, so if same as background default, use default
+ bgcolor = cell.bgcolor ? sheet.colors[cell.bgcolor] : defaultbgcolor;
+ if (bgcolor == defaultcolor) bgcolor = ""; // going to swap, so if same as foreground default, use default
+ spreadsheet.ExecuteCommand("set %C color "+bgcolor+"%Nset %C bgcolor "+color, "");
+ break;
+
+ default:
+ combostr = SocialCalc.SpreadsheetCmdLookup[which] || "";
+ sstr = SocialCalc.SpreadsheetCmdSLookup[which] || "";
+ spreadsheet.ExecuteCommand(combostr, sstr);
+ break;
+ }
+
+ if (obj && obj.blur) obj.blur();
+ SocialCalc.KeyboardFocus();
+
+ }
+
+SocialCalc.SpreadsheetCmdLookup = {
+ 'copy': 'copy %C all',
+ 'cut': 'cut %C all',
+ 'paste': 'paste %C all',
+ 'pasteformats': 'paste %C formats',
+ 'delete': 'erase %C formulas',
+ 'filldown': 'filldown %C all',
+ 'fillright': 'fillright %C all',
+ 'erase': 'erase %C all',
+ 'borderon': 'set %C bt %S%Nset %C br %S%Nset %C bb %S%Nset %C bl %S',
+ 'borderoff': 'set %C bt %S%Nset %C br %S%Nset %C bb %S%Nset %C bl %S',
+ 'merge': 'merge %C',
+ 'unmerge': 'unmerge %C',
+ 'align-left': 'set %C cellformat left',
+ 'align-center': 'set %C cellformat center',
+ 'align-right': 'set %C cellformat right',
+ 'align-default': 'set %C cellformat',
+ 'insertrow': 'insertrow %C',
+ 'insertcol': 'insertcol %C',
+ 'deleterow': 'deleterow %C',
+ 'deletecol': 'deletecol %C',
+ 'undo': 'undo',
+ 'redo': 'redo',
+ 'recalc': 'recalc'
+ }
+
+SocialCalc.SpreadsheetCmdSLookup = {
+ 'borderon': '1px solid rgb(0,0,0)',
+ 'borderoff': ''
+ }
+
+/******* NO LONGER USED
+
+SocialCalc.SpreadsheetCmdTable = {
+ cmd: [
+ {t:"Fill Right", s:"ffal", c:"fillright %C %S"},
+ {t:"Fill Down", s:"ffal", c:"filldown %C %S"},
+ {t:"Copy", s:"all", c:"copy %C %S"},
+ {t:"Cut", s:"all", c:"cut %C %S"},
+ {t:"Paste", s:"ffal", c:"paste %C %S"},
+ {t:"Erase", s:"ffal", c:"erase %C %S"},
+ {t:"Insert", s:"rowcol", c:"insert%S %C"},
+ {t:"Delete", s:"rowcol", c:"delete%S %C"},
+ {t:"Merge Cells", s:"none", c:"merge %C"},
+ {t:"Unmerge", s:"none", c:"unmerge %C"},
+ {t:"Sort", s:"sortcol", c:"sort %R %S"},
+ {t:"Cell Color", s:"colors", c:"set %C color %S"},
+ {t:"Cell Background", s:"colors", c:"set %C bgcolor %S"},
+ {t:"Cell Number Format", s:"ntvf", c:"set %C nontextvalueformat %S"},
+ {t:"Cell Font", s:"fonts", c:"set %C font %S"},
+ {t:"Cell Align", s:"cellformat", c:"set %C cellformat %S"},
+ {t:"Cell Borders", s:"borderOnOff", c:"set %C bt %S%Nset %C br %S%Nset %C bb %S%Nset %C bl %S"},
+ {t:"Column Width", s:"colWidths", c:"set %W width %S"},
+ {t:"Default Color", s:"colors", c:"set sheet defaultcolor %S"},
+ {t:"Default Background", s:"colors", c:"set sheet defaultbgcolor %S"},
+ {t:"Default Number Format", s:"ntvf", c:"set sheet defaultnontextvalueformat %S"},
+ {t:"Default Font", s:"fonts", c:"set sheet defaultfont %S"},
+ {t:"Default Text Align", s:"cellformat", c:"set sheet defaulttextformat %S"},
+ {t:"Default Number Align", s:"cellformat", c:"set sheet defaultnontextformat %S"},
+ {t:"Default Column Width", s:"colWidths", c:"set sheet defaultcolwidth %S"}
+ ],
+ rowcolstuff: [
+ {t:"Insert", s:"rowcol", c:"insert%S %C"},
+ {t:"Delete", s:"rowcol", c:"delete%S %C"},
+ {t:"Paste", s:"ffal", c:"paste %C %S"},
+ {t:"Erase", s:"ffal", c:"erase %C %S"},
+ {t:"Fill Right", s:"ffal", c:"fillright %C %S"},
+ {t:"Fill Down", s:"ffal", c:"filldown %C %S"}
+ ],
+ text: [
+ {t:"Cell Color", s:"colors", c:"set %C color %S"},
+ {t:"Cell Background", s:"colors", c:"set %C bgcolor %S"},
+ {t:"Cell Number Format", s:"ntvf", c:"set %C nontextvalueformat %S"},
+ {t:"Cell Text Format", s:"tvf", c:"set %C textvalueformat %S"},
+ {t:"Cell Font", s:"fonts", c:"set %C font %S"},
+ {t:"Cell Align", s:"cellformat", c:"set %C cellformat %S"},
+ {t:"Default Color", s:"colors", c:"set sheet defaultcolor %S"},
+ {t:"Default Background", s:"colors", c:"set sheet defaultbgcolor %S"},
+ {t:"Default Number Format", s:"ntvf", c:"set sheet defaultnontextvalueformat %S"},
+ {t:"Default Text Format", s:"tvf", c:"set sheet defaulttextvalueformat %S"},
+ {t:"Default Font", s:"fonts", c:"set sheet defaultfont %S"},
+ {t:"Default Text Align", s:"cellformat", c:"set sheet defaulttextformat %S"},
+ {t:"Default Number Align", s:"cellformat", c:"set sheet defaultnontextformat %S"}
+ ],
+ slists: {
+ "colors": [
+ {t:"Default", s:""},
+ {t:"Black", s:"rgb(0,0,0)"},
+ {t:"Dark Gray", s:"rgb(102,102,102)"}, // #666
+ {t:"Gray", s:"rgb(204,204,204)"}, // #CCC
+ {t:"White", s:"rgb(255,255,255)"},
+ {t:"Red", s:"rgb(255,0,0)"},
+ {t:"Dark Red", s:"rgb(153,0,0)"},
+ {t:"Orange", s:"rgb(255,153,0)"},
+ {t:"Yellow", s:"rgb(255,255,0)"},
+ {t:"Light Yellow", s:"rgb(255,255,204)"},
+ {t:"Green", s:"rgb(0,255,0)"},
+ {t:"Dark Green", s:"rgb(0,153,0)"},
+ {t:"Blue", s:"rgb(0,0,255)"},
+ {t:"Dark Blue", s:"rgb(0,0,153)"},
+ {t:"Light Blue", s:"rgb(204,204,255)"}
+ ],
+ "fonts": [ // style weight size family
+ {t:"Default", s:""},
+ {t:"Bold", s:"normal bold * *"},
+ {t:"Italic", s:"italic normal * *"},
+ {t:"Small", s:"* small *"},
+ {t:"Medium", s:"* medium *"},
+ {t:"Large", s:"* large *"},
+ {t:"Bold Small", s:"normal bold small *"},
+ {t:"Bold Medium", s:"normal bold medium *"},
+ {t:"Bold Large", s:"normal bold large *"}
+ ],
+ "cellformat": [
+ {t:"Default", s:""},
+ {t:"Left", s:"left"},
+ {t:"Right", s:"right"},
+ {t:"Center", s:"center"}
+ ],
+ "borderOnOff": [
+ {t:"On", s:"1px solid rgb(0,0,0)"},
+ {t:"Off", s:""}
+ ],
+ "colWidths": [
+ {t:"Default", s:""},
+ {t:"20", s:"20"},
+ {t:"40", s:"40"},
+ {t:"60", s:"60"},
+ {t:"80", s:"80"},
+ {t:"100", s:"100"},
+ {t:"120", s:"120"},
+ {t:"140", s:"140"},
+ {t:"160", s:"160"},
+ {t:"180", s:"180"},
+ {t:"200", s:"200"},
+ {t:"220", s:"220"},
+ {t:"240", s:"240"},
+ {t:"260", s:"260"},
+ {t:"280", s:"280"},
+ {t:"300", s:"300"}
+ ],
+ "ntvf": [
+ {t:"Default", s:""},
+ {t:"1234", s:"0"},
+ {t:"1,234", s:"#,##0"},
+ {t:"1,234.5", s:"#,##0.0"},
+ {t:"1,234.56", s:"#,##0.00"},
+ {t:"1,234.567", s:"#,##0.000"},
+ {t:"1,234%", s:"#,##0%"},
+ {t:"1,234.5%", s:"#,##0.0%"},
+ {t:"(1,234)", s:"#,##0_);(#,##0)"},
+ {t:"(1,234.5)", s:"#,##0.0_);(#,##0.0)"},
+ {t:"(1,234.56)", s:"#,##0.00_);(#,##0.00)"},
+ {t:"00", s:"00"},
+ {t:"000", s:"000"},
+ {t:"0000", s:"0000"},
+ {t:"$1,234.56", s:"$#,##0.00"},
+ {t:"2006-01-04", s:"yyyy-mm-dd"},
+ {t:"01:23:45", s:"hh:mm:ss"},
+ {t:"2006-01-04 01:23:45", s:"yyyy-mm-dd hh:mm:ss"},
+ {t:"Hidden", s:"hidden"}
+ ],
+ "tvf": [
+ {t:"Default", s:""},
+ {t:"Automatic", s:"general"},
+ {t:"Plain Text", s:"text-plain"},
+ {t:"HTML", s:"text-html"},
+ {t:"Wiki", s:"text-wiki"},
+ {t:"Hidden", s:"hidden"}
+ ],
+ "ffal": [ // Formulas, Formats, All
+ {t:"All", s:"all"},
+ {t:"Contents", s:"formulas"},
+ {t:"Formats", s:"formats"}
+ ],
+ "all": [ // All
+ {t:"All", s:"all"}
+ ],
+ "rowcol": [
+ {t:"Row", s:"row"},
+ {t:"Column", s:"col"}
+ ],
+ "sortcol": [
+ {t:"A up", s:"A up"},
+ {t:"B up", s:"B up"},
+ {t:"C up", s:"C up"},
+ {t:"A down", s:"A down"},
+ {t:"B down", s:"B down"},
+ {t:"C down", s:"C down"},
+ {t:"A, B, C up", s:"A up B up C up"}
+ ],
+ "none": [ // nothing
+ {t:" ", s:" "}
+ ]
+ }
+ }
+*********/
+
+//
+// SocialCalc.SpreadsheetControlExecuteCommand(obj, combostr, sstr)
+//
+// xxx
+//
+
+SocialCalc.SpreadsheetControlExecuteCommand = function(obj, combostr, sstr) {
+
+ var i, commands;
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var eobj = spreadsheet.editor;
+
+ var str = {};
+ str.P = "%";
+ str.N = "\n"
+ if (eobj.range.hasrange) {
+ str.R = SocialCalc.crToCoord(eobj.range.left, eobj.range.top)+
+ ":"+SocialCalc.crToCoord(eobj.range.right, eobj.range.bottom);
+ str.C = str.R;
+ str.W = SocialCalc.rcColname(eobj.range.left) + ":" + SocialCalc.rcColname(eobj.range.right);
+ }
+ else {
+ str.C = eobj.ecell.coord;
+ str.R = eobj.ecell.coord+":"+eobj.ecell.coord;
+ str.W = SocialCalc.rcColname(SocialCalc.coordToCr(eobj.ecell.coord).col);
+ }
+ str.S = sstr;
+ combostr = combostr.replace(/%C/g, str.C);
+ combostr = combostr.replace(/%R/g, str.R);
+ combostr = combostr.replace(/%N/g, str.N);
+ combostr = combostr.replace(/%S/g, str.S);
+ combostr = combostr.replace(/%W/g, str.W);
+ combostr = combostr.replace(/%P/g, str.P);
+
+ eobj.EditorScheduleSheetCommands(combostr);
+
+ }
+
+//
+// result = SocialCalc.SpreadsheetControlCreateSheetHTML(spreadsheet)
+//
+// Returns the HTML representation of the whole spreadsheet
+//
+
+SocialCalc.SpreadsheetControlCreateSheetHTML = function(spreadsheet) {
+
+ var context, div, ele;
+
+ var result = "";
+
+ context = new SocialCalc.RenderContext(spreadsheet.sheet);
+ div = document.createElement("div");
+ ele = context.RenderSheet(null, {type: "html"});
+ div.appendChild(ele);
+ delete context;
+ result = div.innerHTML;
+ delete ele;
+ delete div;
+ return result;
+
+ }
+
+//
+// result = SocialCalc.SpreadsheetControlCreateCellHTML(spreadsheet, coord, linkstyle)
+//
+// Returns the HTML representation of a cell. Blank is "", not "&nbsp;".
+//
+
+SocialCalc.SpreadsheetControlCreateCellHTML = function(spreadsheet, coord, linkstyle) {
+
+ var result = "";
+ var cell = spreadsheet.sheet.cells[coord];
+
+ if (!cell) return "";
+
+ if (cell.displaystring == undefined) {
+ result = SocialCalc.FormatValueForDisplay(spreadsheet.sheet, cell.datavalue, coord, (linkstyle || spreadsheet.context.defaultHTMLlinkstyle));
+ }
+ else {
+ result = cell.displaystring;
+ }
+
+ if (result == "&nbsp;") result = "";
+
+ return result;
+
+ }
+
+//
+// result = SocialCalc.SpreadsheetControlCreateCellHTMLSave(spreadsheet, range, linkstyle)
+//
+// Returns the HTML representation of a range of cells, or the whole sheet if range is null.
+// The form is:
+// version:1.0
+// coord:cell-HTML
+// coord:cell-HTML
+// ...
+//
+// Empty cells are skipped. The cell-HTML is encoded with ":"=>"\c", newline=>"\n", and "\"=>"\b".
+//
+
+SocialCalc.SpreadsheetControlCreateCellHTMLSave = function(spreadsheet, range, linkstyle) {
+
+ var cr1, cr2, row, col, coord, cell, cellHTML;
+ var result = [];
+ var prange;
+
+ if (range) {
+ prange = SocialCalc.ParseRange(range);
+ }
+ else {
+ prange = {cr1: {row: 1, col:1},
+ cr2: {row: spreadsheet.sheet.attribs.lastrow, col: spreadsheet.sheet.attribs.lastcol}};
+ }
+ cr1 = prange.cr1;
+ cr2 = prange.cr2;
+
+ result.push("version:1.0");
+
+ for (row=cr1.row; row <= cr2.row; row++) {
+ for (col=cr1.col; col <= cr2.col; col++) {
+ coord = SocialCalc.crToCoord(col, row);
+ cell=spreadsheet.sheet.cells[coord];
+ if (!cell) continue;
+ if (cell.displaystring == undefined) {
+ cellHTML = SocialCalc.FormatValueForDisplay(spreadsheet.sheet, cell.datavalue, coord, (linkstyle || spreadsheet.context.defaultHTMLlinkstyle));
+ }
+ else {
+ cellHTML = cell.displaystring;
+ }
+ if (cellHTML == "&nbsp;") continue;
+ result.push(coord+":"+SocialCalc.encodeForSave(cellHTML));
+ }
+ }
+
+ result.push(""); // one extra to get extra \n
+ return result.join("\n");
+ }
+
+//
+// Formula Bar Button Routines
+//
+
+SocialCalc.SpreadsheetControl.DoFunctionList = function() {
+
+ var i, cname, str, f, ele;
+
+ var scf = SocialCalc.Formula;
+ var scc = SocialCalc.Constants;
+ var fcl = scc.function_classlist;
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var idp = spreadsheet.idPrefix+"function";
+
+ ele = document.getElementById(idp+"dialog");
+ if (ele) return; // already have one
+
+ scf.FillFunctionInfo();
+
+ str = '<table><tr><td><span style="font-size:x-small;font-weight:bold">%loc!Category!</span><br>'+
+ '<select id="'+idp+'class" size="'+fcl.length+'" style="width:120px;" onchange="SocialCalc.SpreadsheetControl.FunctionClassChosen(this.options[this.selectedIndex].value);">';
+ for (i=0; i<fcl.length; i++) {
+ str += '<option value="'+fcl[i]+'"'+(i==0?' selected>':'>')+SocialCalc.special_chars(scf.FunctionClasses[fcl[i]].name)+'</option>';
+ }
+ str += '</select></td><td>&nbsp;&nbsp;</td><td id="'+idp+'list"><span style="font-size:x-small;font-weight:bold">%loc!Functions!</span><br>'+
+ '<select id="'+idp+'name" size="'+fcl.length+'" style="width:240px;" '+
+ 'onchange="SocialCalc.SpreadsheetControl.FunctionChosen(this.options[this.selectedIndex].value);" ondblclick="SocialCalc.SpreadsheetControl.DoFunctionPaste();">';
+ str += SocialCalc.SpreadsheetControl.GetFunctionNamesStr("all");
+ str += '</td></tr><tr><td colspan="3">'+
+ '<div id="'+idp+'desc" style="width:380px;height:80px;overflow:auto;font-size:x-small;">'+SocialCalc.SpreadsheetControl.GetFunctionInfoStr(scf.FunctionClasses[fcl[0]].items[0])+'</div>'+
+ '<div style="width:380px;text-align:right;padding-top:6px;font-size:small;">'+
+ '<input type="button" value="%loc!Paste!" style="font-size:smaller;" onclick="SocialCalc.SpreadsheetControl.DoFunctionPaste();">&nbsp;'+
+ '<input type="button" value="%loc!Cancel!" style="font-size:smaller;" onclick="SocialCalc.SpreadsheetControl.HideFunctions();"></div>'+
+ '</td></tr></table>';
+
+ var main = document.createElement("div");
+ main.id = idp+"dialog";
+
+ main.style.position = "absolute";
+
+ var vp = SocialCalc.GetViewportInfo();
+
+ main.style.top = (vp.height/3)+"px";
+ main.style.left = (vp.width/3)+"px";
+ main.style.zIndex = 100;
+ main.style.backgroundColor = "#FFF";
+ main.style.border = "1px solid black";
+
+ main.style.width = "400px";
+
+ str = '<table cellspacing="0" cellpadding="0" style="border-bottom:1px solid black;"><tr>'+
+ '<td style="font-size:10px;cursor:default;width:100%;background-color:#999;color:#FFF;">'+"&nbsp;%loc!Function List!"+'</td>'+
+ '<td style="font-size:10px;cursor:default;color:#666;" onclick="SocialCalc.SpreadsheetControl.HideFunctions();">&nbsp;X&nbsp;</td></tr></table>'+
+ '<div style="background-color:#DDD;">'+str+'</div>';
+
+ str = SocialCalc.LocalizeSubstrings(str);
+
+ main.innerHTML = str;
+
+ SocialCalc.DragRegister(main.firstChild.firstChild.firstChild.firstChild, true, true, {MouseDown: SocialCalc.DragFunctionStart, MouseMove: SocialCalc.DragFunctionPosition,
+ MouseUp: SocialCalc.DragFunctionPosition,
+ Disabled: null, positionobj: main});
+
+ spreadsheet.spreadsheetDiv.appendChild(main);
+
+ ele = document.getElementById(idp+"name");
+ ele.focus();
+ SocialCalc.CmdGotFocus(ele);
+//!!! need to do keyboard handling: if esc, hide; if All, letter scrolls to there
+
+ }
+
+SocialCalc.SpreadsheetControl.GetFunctionNamesStr = function(cname) {
+
+ var i, f;
+ var scf = SocialCalc.Formula;
+ var str = "";
+
+ f = scf.FunctionClasses[cname];
+ for (i=0; i<f.items.length; i++) {
+ str += '<option value="'+f.items[i]+'"'+(i==0?' selected>':'>')+f.items[i]+'</option>';
+ }
+
+ return str;
+
+ }
+
+SocialCalc.SpreadsheetControl.FillFunctionNames = function(cname, ele) {
+
+ var i, f;
+ var scf = SocialCalc.Formula;
+
+ ele.length = 0;
+ f = scf.FunctionClasses[cname];
+ for (i=0; i<f.items.length; i++) {
+ ele.options[i] = new Option(f.items[i], f.items[i]);
+ if (i==0) {
+ ele.options[i].selected = true;
+ }
+ }
+ }
+
+SocialCalc.SpreadsheetControl.GetFunctionInfoStr = function(fname) {
+
+ var scf = SocialCalc.Formula;
+ var f = scf.FunctionList[fname];
+ var scsc = SocialCalc.special_chars;
+
+ var str = "<b>"+fname+"("+scsc(scf.FunctionArgString(fname))+")</b><br>";
+ str += scsc(f[3]);
+
+ return str;
+
+ }
+
+SocialCalc.SpreadsheetControl.FunctionClassChosen = function(cname) {
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var idp = spreadsheet.idPrefix+"function";
+ var scf = SocialCalc.Formula;
+
+ SocialCalc.SpreadsheetControl.FillFunctionNames(cname, document.getElementById(idp+"name"));
+
+ SocialCalc.SpreadsheetControl.FunctionChosen(scf.FunctionClasses[cname].items[0]);
+
+ }
+
+SocialCalc.SpreadsheetControl.FunctionChosen = function(fname) {
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var idp = spreadsheet.idPrefix+"function";
+
+ document.getElementById(idp+"desc").innerHTML = SocialCalc.SpreadsheetControl.GetFunctionInfoStr(fname);
+
+ }
+
+SocialCalc.SpreadsheetControl.HideFunctions = function() {
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+
+ var ele = document.getElementById(spreadsheet.idPrefix+"functiondialog");
+ ele.innerHTML = "";
+
+ SocialCalc.DragUnregister(ele);
+
+ SocialCalc.KeyboardFocus();
+
+ if (ele.parentNode) {
+ ele.parentNode.removeChild(ele);
+ }
+
+ }
+
+SocialCalc.SpreadsheetControl.DoFunctionPaste = function() {
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var editor = spreadsheet.editor;
+ var ele = document.getElementById(spreadsheet.idPrefix+"functionname");
+ var mele = document.getElementById(spreadsheet.idPrefix+"multilinetextarea");
+
+ var text = ele.value+"(";
+
+ SocialCalc.SpreadsheetControl.HideFunctions();
+
+ if (mele) { // multi-line editing is in progress
+ mele.value += text;
+ mele.focus();
+ SocialCalc.CmdGotFocus(mele);
+ }
+ else {
+ editor.EditorAddToInput(text, "=");
+ }
+
+ }
+
+
+SocialCalc.SpreadsheetControl.DoMultiline = function() {
+
+ var SCLocSS = SocialCalc.LocalizeSubstrings;
+
+ var str, ele, text;
+
+ var scc = SocialCalc.Constants;
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var editor = spreadsheet.editor;
+ var wval = editor.workingvalues;
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var idp = spreadsheet.idPrefix+"multiline";
+
+ ele = document.getElementById(idp+"dialog");
+ if (ele) return; // already have one
+
+ switch (editor.state) {
+ case "start":
+ wval.ecoord = editor.ecell.coord;
+ wval.erow = editor.ecell.row;
+ wval.ecol = editor.ecell.col;
+ editor.RangeRemove();
+ text = SocialCalc.GetCellContents(editor.context.sheetobj, wval.ecoord);
+ break;
+
+ case "input":
+ case "inputboxdirect":
+ text = editor.inputBox.GetText();
+ break;
+ }
+
+ editor.inputBox.element.disabled = true;
+
+ text = SocialCalc.special_chars(text);
+
+ str = '<textarea id="'+idp+'textarea" style="width:380px;height:120px;margin:10px 0px 0px 6px;">'+text+'</textarea>'+
+ '<div style="width:380px;text-align:right;padding:6px 0px 4px 6px;font-size:small;">'+
+ SCLocSS('<input type="button" value="%loc!Set Cell Contents!" style="font-size:smaller;" onclick="SocialCalc.SpreadsheetControl.DoMultilinePaste();">&nbsp;'+
+ '<input type="button" value="%loc!Clear!" style="font-size:smaller;" onclick="SocialCalc.SpreadsheetControl.DoMultilineClear();">&nbsp;'+
+ '<input type="button" value="%loc!Cancel!" style="font-size:smaller;" onclick="SocialCalc.SpreadsheetControl.HideMultiline();"></div>'+
+ '</div>');
+
+ var main = document.createElement("div");
+ main.id = idp+"dialog";
+
+ main.style.position = "absolute";
+
+ var vp = SocialCalc.GetViewportInfo();
+
+ main.style.top = (vp.height/3)+"px";
+ main.style.left = (vp.width/3)+"px";
+ main.style.zIndex = 100;
+ main.style.backgroundColor = "#FFF";
+ main.style.border = "1px solid black";
+
+ main.style.width = "400px";
+
+ main.innerHTML = '<table cellspacing="0" cellpadding="0" style="border-bottom:1px solid black;"><tr>'+
+ '<td style="font-size:10px;cursor:default;width:100%;background-color:#999;color:#FFF;">'+
+ SCLocSS("&nbsp;%loc!Multi-line Input Box!")+'</td>'+
+ '<td style="font-size:10px;cursor:default;color:#666;" onclick="SocialCalc.SpreadsheetControl.HideMultiline();">&nbsp;X&nbsp;</td></tr></table>'+
+ '<div style="background-color:#DDD;">'+str+'</div>';
+
+ SocialCalc.DragRegister(main.firstChild.firstChild.firstChild.firstChild, true, true, {MouseDown: SocialCalc.DragFunctionStart, MouseMove: SocialCalc.DragFunctionPosition,
+ MouseUp: SocialCalc.DragFunctionPosition,
+ Disabled: null, positionobj: main});
+
+ spreadsheet.spreadsheetDiv.appendChild(main);
+
+ ele = document.getElementById(idp+"textarea");
+ ele.focus();
+ SocialCalc.CmdGotFocus(ele);
+//!!! need to do keyboard handling: if esc, hide?
+
+ }
+
+
+SocialCalc.SpreadsheetControl.HideMultiline = function() {
+
+ var scc = SocialCalc.Constants;
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var editor = spreadsheet.editor;
+
+ var ele = document.getElementById(spreadsheet.idPrefix+"multilinedialog");
+ ele.innerHTML = "";
+
+ SocialCalc.DragUnregister(ele);
+
+ SocialCalc.KeyboardFocus();
+
+ if (ele.parentNode) {
+ ele.parentNode.removeChild(ele);
+ }
+
+ switch (editor.state) {
+ case "start":
+ editor.inputBox.DisplayCellContents(null);
+ break;
+
+ case "input":
+ case "inputboxdirect":
+ editor.inputBox.element.disabled = false;
+ editor.inputBox.Focus();
+ break;
+ }
+
+ }
+
+SocialCalc.SpreadsheetControl.DoMultilineClear = function() {
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+
+ var ele = document.getElementById(spreadsheet.idPrefix+"multilinetextarea");
+
+ ele.value = "";
+ ele.focus();
+
+ }
+
+
+SocialCalc.SpreadsheetControl.DoMultilinePaste = function() {
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var editor = spreadsheet.editor;
+ var wval = editor.workingvalues;
+
+ var ele = document.getElementById(spreadsheet.idPrefix+"multilinetextarea");
+
+ var text = ele.value;
+
+ SocialCalc.SpreadsheetControl.HideMultiline();
+
+ switch (editor.state) {
+ case "start":
+ wval.partialexpr = "";
+ wval.ecoord = editor.ecell.coord;
+ wval.erow = editor.ecell.row;
+ wval.ecol = editor.ecell.col;
+ break;
+ case "input":
+ case "inputboxdirect":
+ editor.inputBox.Blur();
+ editor.inputBox.ShowInputBox(false);
+ editor.state = "start";
+ break;
+ }
+
+ editor.EditorSaveEdit(text);
+
+ }
+
+
+SocialCalc.SpreadsheetControl.DoLink = function() {
+
+ var SCLoc = SocialCalc.LocalizeString;
+
+ var str, ele, text, cell, setformat, popup;
+
+ var scc = SocialCalc.Constants;
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var editor = spreadsheet.editor;
+ var wval = editor.workingvalues;
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var idp = spreadsheet.idPrefix+"link";
+
+ ele = document.getElementById(idp+"dialog");
+ if (ele) return; // already have one
+
+ switch (editor.state) {
+ case "start":
+ wval.ecoord = editor.ecell.coord;
+ wval.erow = editor.ecell.row;
+ wval.ecol = editor.ecell.col;
+ editor.RangeRemove();
+ text = SocialCalc.GetCellContents(editor.context.sheetobj, wval.ecoord);
+ break;
+
+ case "input":
+ case "inputboxdirect":
+ text = editor.inputBox.GetText();
+ break;
+ }
+
+ editor.inputBox.element.disabled = true;
+
+ if (text.charAt(0)=="'") {
+ text = text.slice(1);
+ }
+
+ var parts = SocialCalc.ParseCellLinkText(text);
+
+ text = SocialCalc.special_chars(text);
+
+ cell = spreadsheet.sheet.cells[editor.ecell.coord];
+ if (!cell || !cell.textvalueformat) { // set to link format, but don't override
+ setformat = " checked";
+ }
+ else {
+ setformat = "";
+ }
+
+ popup = parts.newwin ? " checked" : "";
+
+ str = '<div style="padding:6px 0px 4px 6px;">'+
+ '<span style="font-size:smaller;">'+SCLoc("Description")+'</span><br>'+
+ '<input type="text" id="'+idp+'desc" style="width:380px;" value="'+SocialCalc.special_chars(parts.desc)+'"><br>'+
+ '<span style="font-size:smaller;">'+SCLoc("URL")+'</span><br>'+
+ '<input type="text" id="'+idp+'url" style="width:380px;" value="'+SocialCalc.special_chars(parts.url)+'"><br>';
+ if (SocialCalc.Callbacks.MakePageLink) { // only show if handling pagenames here
+ str += '<span style="font-size:smaller;">'+SCLoc("Page Name")+'</span><br>'+
+ '<input type="text" id="'+idp+'pagename" style="width:380px;" value="'+SocialCalc.special_chars(parts.pagename)+'"><br>'+
+ '<span style="font-size:smaller;">'+SCLoc("Workspace")+'</span><br>'+
+ '<input type="text" id="'+idp+'workspace" style="width:380px;" value="'+SocialCalc.special_chars(parts.workspace)+'"><br>';
+ }
+ str += SocialCalc.LocalizeSubstrings('<input type="checkbox" id="'+idp+'format"'+setformat+'>&nbsp;'+
+ '<span style="font-size:smaller;">%loc!Set to Link format!</span><br>'+
+ '<input type="checkbox" id="'+idp+'popup"'+popup+'>&nbsp;'+
+ '<span style="font-size:smaller;">%loc!Show in new browser window!</span>'+
+ '</div>'+
+ '<div style="width:380px;text-align:right;padding:6px 0px 4px 6px;font-size:small;">'+
+ '<input type="button" value="%loc!Set Cell Contents!" style="font-size:smaller;" onclick="SocialCalc.SpreadsheetControl.DoLinkPaste();">&nbsp;'+
+ '<input type="button" value="%loc!Clear!" style="font-size:smaller;" onclick="SocialCalc.SpreadsheetControl.DoLinkClear();">&nbsp;'+
+ '<input type="button" value="%loc!Cancel!" style="font-size:smaller;" onclick="SocialCalc.SpreadsheetControl.HideLink();"></div>'+
+ '</div>');
+
+ var main = document.createElement("div");
+ main.id = idp+"dialog";
+
+ main.style.position = "absolute";
+
+ var vp = SocialCalc.GetViewportInfo();
+
+ main.style.top = (vp.height/3)+"px";
+ main.style.left = (vp.width/3)+"px";
+ main.style.zIndex = 100;
+ main.style.backgroundColor = "#FFF";
+ main.style.border = "1px solid black";
+
+ main.style.width = "400px";
+
+ main.innerHTML = '<table cellspacing="0" cellpadding="0" style="border-bottom:1px solid black;"><tr>'+
+ '<td style="font-size:10px;cursor:default;width:100%;background-color:#999;color:#FFF;">'+"&nbsp;"+SCLoc("Link Input Box")+'</td>'+
+ '<td style="font-size:10px;cursor:default;color:#666;" onclick="SocialCalc.SpreadsheetControl.HideLink();">&nbsp;X&nbsp;</td></tr></table>'+
+ '<div style="background-color:#DDD;">'+str+'</div>';
+
+ SocialCalc.DragRegister(main.firstChild.firstChild.firstChild.firstChild, true, true, {MouseDown: SocialCalc.DragFunctionStart, MouseMove: SocialCalc.DragFunctionPosition,
+ MouseUp: SocialCalc.DragFunctionPosition,
+ Disabled: null, positionobj: main});
+
+ spreadsheet.spreadsheetDiv.appendChild(main);
+
+ ele = document.getElementById(idp+"url");
+ ele.focus();
+ SocialCalc.CmdGotFocus(ele);
+//!!! need to do keyboard handling: if esc, hide?
+
+ }
+
+
+SocialCalc.SpreadsheetControl.HideLink = function() {
+
+ var scc = SocialCalc.Constants;
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var editor = spreadsheet.editor;
+
+ var ele = document.getElementById(spreadsheet.idPrefix+"linkdialog");
+ ele.innerHTML = "";
+
+ SocialCalc.DragUnregister(ele);
+
+ SocialCalc.KeyboardFocus();
+
+ if (ele.parentNode) {
+ ele.parentNode.removeChild(ele);
+ }
+
+ switch (editor.state) {
+ case "start":
+ editor.inputBox.DisplayCellContents(null);
+ break;
+
+ case "input":
+ case "inputboxdirect":
+ editor.inputBox.element.disabled = false;
+ editor.inputBox.Focus();
+ break;
+ }
+
+ }
+
+SocialCalc.SpreadsheetControl.DoLinkClear = function() {
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+
+ document.getElementById(spreadsheet.idPrefix+"linkdesc").value = "";
+ document.getElementById(spreadsheet.idPrefix+"linkpagename").value = "";
+ document.getElementById(spreadsheet.idPrefix+"linkworkspace").value = "";
+
+ var ele = document.getElementById(spreadsheet.idPrefix+"linkurl");
+ ele.value = "";
+ ele.focus();
+
+ }
+
+
+SocialCalc.SpreadsheetControl.DoLinkPaste = function() {
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var editor = spreadsheet.editor;
+ var wval = editor.workingvalues;
+
+ var descele = document.getElementById(spreadsheet.idPrefix+"linkdesc");
+ var urlele = document.getElementById(spreadsheet.idPrefix+"linkurl");
+ var pagenameele = document.getElementById(spreadsheet.idPrefix+"linkpagename");
+ var workspaceele = document.getElementById(spreadsheet.idPrefix+"linkworkspace");
+ var formatele = document.getElementById(spreadsheet.idPrefix+"linkformat");
+ var popupele = document.getElementById(spreadsheet.idPrefix+"linkpopup");
+
+ var text = "";
+
+ var ltsym, gtsym, obsym, cbsym;
+
+ if (popupele.checked) {
+ ltsym = "<<"; gtsym = ">>"; obsym = "[["; cbsym = "]]";
+ }
+ else {
+ ltsym = "<"; gtsym = ">"; obsym = "["; cbsym = "]";
+ }
+
+ if (pagenameele && pagenameele.value) {
+ if (workspaceele.value) {
+ text = descele.value+"{"+workspaceele.value+obsym+pagenameele.value+cbsym+"}";
+ }
+ else {
+ text = descele.value+obsym+pagenameele.value+cbsym;
+ }
+ }
+ else {
+ text = descele.value+ltsym+urlele.value+gtsym;
+ }
+
+ SocialCalc.SpreadsheetControl.HideLink();
+
+ switch (editor.state) {
+ case "start":
+ wval.partialexpr = "";
+ wval.ecoord = editor.ecell.coord;
+ wval.erow = editor.ecell.row;
+ wval.ecol = editor.ecell.col;
+ break;
+ case "input":
+ case "inputboxdirect":
+ editor.inputBox.Blur();
+ editor.inputBox.ShowInputBox(false);
+ editor.state = "start";
+ break;
+ }
+
+ if (formatele.checked) {
+ SocialCalc.SpreadsheetControlExecuteCommand(null, "set %C textvalueformat text-link", "");
+ }
+
+ editor.EditorSaveEdit(text);
+
+ }
+
+SocialCalc.SpreadsheetControl.DoSum = function() {
+
+ var cmd, cell, row, col, sel, cr, foundvalue;
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var editor = spreadsheet.editor;
+ var sheet = editor.context.sheetobj;
+
+ if (editor.range.hasrange) {
+ sel = SocialCalc.crToCoord(editor.range.left, editor.range.top)+
+ ":"+SocialCalc.crToCoord(editor.range.right, editor.range.bottom);
+ cmd = "set "+SocialCalc.crToCoord(editor.range.right, editor.range.bottom+1)+
+ " formula sum("+sel+")";
+ }
+ else {
+ row = editor.ecell.row - 1;
+ col = editor.ecell.col;
+ if (row<=1) {
+ cmd = "set "+editor.ecell.coord+" constant e#REF! 0 #REF!";
+ }
+ else {
+ foundvalue = false;
+ while (row>0) {
+ cr = SocialCalc.crToCoord(col, row);
+ cell = sheet.GetAssuredCell(cr);
+ if (!cell.datatype || cell.datatype=="t") {
+ if (foundvalue) {
+ row++;
+ break;
+ }
+ }
+ else {
+ foundvalue = true;
+ }
+ row--;
+ }
+ cmd = "set "+editor.ecell.coord+" formula sum("+
+ SocialCalc.crToCoord(col,row)+":"+SocialCalc.crToCoord(col, editor.ecell.row-1)+")";
+ }
+ }
+
+ editor.EditorScheduleSheetCommands(cmd);
+
+ }
+
+
+//
+// TAB Routines
+//
+
+// Sort
+
+SocialCalc.SpreadsheetControlSortOnclick = function(s, t) {
+
+ var name, i;
+ var namelist = [];
+ var nl = document.getElementById(s.idPrefix+"sortlist");
+ SocialCalc.LoadColumnChoosers(s);
+ s.editor.RangeChangeCallback.sort = SocialCalc.UpdateSortRangeProposal;
+
+ for (name in s.sheet.names) {
+ namelist.push(name);
+ }
+ namelist.sort();
+ nl.length = 0;
+ nl.options[0] = new Option(SocialCalc.LocalizeString("[select range]"));
+ for (i=0; i<namelist.length; i++) {
+ name = namelist[i];
+ nl.options[i+1] = new Option(name, name);
+ if (name == s.sortrange) {
+ nl.options[i+1].selected = true;
+ }
+ }
+ if (s.sortrange == "") {
+ nl.options[0].selected = true;
+ }
+
+ SocialCalc.UpdateSortRangeProposal(s.editor);
+ SocialCalc.KeyboardFocus();
+ return;
+
+ }
+
+SocialCalc.SpreadsheetControlSortSave = function(editor, setting) {
+ // Format is:
+ // sort:sortrange:major:up/down:minor:up/down:last:up/down
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+ var str, sele, rele;
+
+ str = "sort:"+SocialCalc.encodeForSave(spreadsheet.sortrange)+":";
+ sele = document.getElementById(spreadsheet.idPrefix+"majorsort");
+ rele = document.getElementById(spreadsheet.idPrefix+"majorsortup");
+ str += sele.selectedIndex + (rele.checked ? ":up" : ":down");
+ sele = document.getElementById(spreadsheet.idPrefix+"minorsort");
+ if (sele.selectedIndex>0) {
+ rele = document.getElementById(spreadsheet.idPrefix+"minorsortup");
+ str += ":"+sele.selectedIndex + (rele.checked ? ":up" : ":down");
+ }
+ else {
+ str += "::";
+ }
+ sele = document.getElementById(spreadsheet.idPrefix+"lastsort");
+ if (sele.selectedIndex>0) {
+ rele = document.getElementById(spreadsheet.idPrefix+"lastsortup");
+ str += ":"+sele.selectedIndex + (rele.checked ? ":up" : ":down");
+ }
+ else {
+ str += "::";
+ }
+ return str+"\n";
+ }
+
+SocialCalc.SpreadsheetControlSortLoad = function(editor, setting, line, flags) {
+ var parts, ele;
+
+ var spreadsheet = SocialCalc.GetSpreadsheetControlObject();
+
+ parts = line.split(":");
+ spreadsheet.sortrange = SocialCalc.decodeFromSave(parts[1]);
+ ele = document.getElementById(spreadsheet.idPrefix+"sortbutton");
+ if (spreadsheet.sortrange) {
+ ele.value = SocialCalc.LocalizeString("Sort ")+spreadsheet.sortrange;
+ ele.style.visibility = "visible";
+ }
+ else {
+ ele.style.visibility = "hidden";
+ }
+ SocialCalc.LoadColumnChoosers(spreadsheet);
+
+ sele = document.getElementById(spreadsheet.idPrefix+"majorsort");
+ sele.selectedIndex = parts[2]-0;
+ document.getElementById(spreadsheet.idPrefix+"majorsort"+parts[3]).checked = true;
+ sele = document.getElementById(spreadsheet.idPrefix+"minorsort");
+ if (parts[4]) {
+ sele.selectedIndex = parts[4]-0;
+ document.getElementById(spreadsheet.idPrefix+"minorsort"+parts[5]).checked = true;
+ }
+ else {
+ sele.selectedIndex = 0;
+ document.getElementById(spreadsheet.idPrefix+"minorsortup").checked = true;
+ }
+ sele = document.getElementById(spreadsheet.idPrefix+"lastsort");
+ if (parts[6]) {
+ sele.selectedIndex = parts[6]-0;
+ document.getElementById(spreadsheet.idPrefix+"lastsort"+parts[7]).checked = true;
+ }
+ else {
+ sele.selectedIndex = 0;
+ document.getElementById(spreadsheet.idPrefix+"lastsortup").checked = true;
+ }
+
+ return true;
+ }
+
+// Comment
+
+SocialCalc.SpreadsheetControlCommentOnclick = function(s, t) {
+ s.editor.MoveECellCallback.comment = SocialCalc.SpreadsheetControlCommentMoveECell;
+ SocialCalc.SpreadsheetControlCommentDisplay(s, t);
+ SocialCalc.KeyboardFocus();
+ return;
+ }
+
+SocialCalc.SpreadsheetControlCommentDisplay = function(s, t) {
+ var c = "";
+ if (s.editor.ecell && s.editor.ecell.coord && s.sheet.cells[s.editor.ecell.coord]) {
+ c = s.sheet.cells[s.editor.ecell.coord].comment || "";
+ }
+ document.getElementById(s.idPrefix+"commenttext").value = c;
+ }
+
+SocialCalc.SpreadsheetControlCommentMoveECell = function(editor) {
+ SocialCalc.SpreadsheetControlCommentDisplay(SocialCalc.GetSpreadsheetControlObject(), "comment");
+ }
+
+SocialCalc.SpreadsheetControlCommentSet = function() {
+ var s=SocialCalc.GetSpreadsheetControlObject();
+ s.ExecuteCommand("set %C comment "+SocialCalc.encodeForSave(document.getElementById(s.idPrefix+"commenttext").value));
+ var cell=SocialCalc.GetEditorCellElement(s.editor, s.editor.ecell.row, s.editor.ecell.col);
+ s.editor.UpdateCellCSS(cell, s.editor.ecell.row, s.editor.ecell.col);
+ SocialCalc.KeyboardFocus();
+ }
+
+SocialCalc.SpreadsheetControlCommentOnunclick = function(s, t) {
+ delete s.editor.MoveECellCallback.comment;
+ }
+
+// Names
+
+SocialCalc.SpreadsheetControlNamesOnclick = function(s, t) {
+ document.getElementById(s.idPrefix+"namesname").value = "";
+ document.getElementById(s.idPrefix+"namesdesc").value = "";
+ document.getElementById(s.idPrefix+"namesvalue").value = "";
+ s.editor.RangeChangeCallback.names = SocialCalc.SpreadsheetControlNamesRangeChange;
+ s.editor.MoveECellCallback.names = SocialCalc.SpreadsheetControlNamesRangeChange;
+ SocialCalc.SpreadsheetControlNamesRangeChange(s.editor);
+ SocialCalc.SpreadsheetControlNamesFillNameList();
+ SocialCalc.SpreadsheetControlNamesChangedName();
+ }
+
+SocialCalc.SpreadsheetControlNamesFillNameList = function() {
+ var SCLoc = SocialCalc.LocalizeString;
+ var name, i;
+ var namelist = [];
+ var s=SocialCalc.GetSpreadsheetControlObject();
+ var nl = document.getElementById(s.idPrefix+"nameslist");
+ var currentname = document.getElementById(s.idPrefix+"namesname").value.toUpperCase().replace(/[^A-Z0-9_\.]/g, "");
+ for (name in s.sheet.names) {
+ namelist.push(name);
+ }
+ namelist.sort();
+ nl.length = 0;
+ if (namelist.length > 0) {
+ nl.options[0] = new Option(SCLoc("[New]"));
+ }
+ else {
+ nl.options[0] = new Option(SCLoc("[None]"));
+ }
+ for (i=0; i<namelist.length; i++) {
+ name = namelist[i];
+ nl.options[i+1] = new Option(name, name);
+ if (name == currentname) {
+ nl.options[i+1].selected = true;
+ }
+ }
+ if (currentname == "") {
+ nl.options[0].selected = true;
+ }
+ }
+
+SocialCalc.SpreadsheetControlNamesChangedName = function() {
+ var s=SocialCalc.GetSpreadsheetControlObject();
+ var nl = document.getElementById(s.idPrefix+"nameslist");
+ var name = nl.options[nl.selectedIndex].value;
+ if (s.sheet.names[name]) {
+ document.getElementById(s.idPrefix+"namesname").value = name;
+ document.getElementById(s.idPrefix+"namesdesc").value = s.sheet.names[name].desc || "";
+ document.getElementById(s.idPrefix+"namesvalue").value = s.sheet.names[name].definition || "";
+ }
+ else {
+ document.getElementById(s.idPrefix+"namesname").value = "";
+ document.getElementById(s.idPrefix+"namesdesc").value = "";
+ document.getElementById(s.idPrefix+"namesvalue").value = "";
+ }
+ }
+
+SocialCalc.SpreadsheetControlNamesRangeChange = function(editor) {
+ var s = SocialCalc.GetSpreadsheetControlObject();
+ var ele = document.getElementById(s.idPrefix+"namesrangeproposal");
+ if (editor.range.hasrange) {
+ ele.value = SocialCalc.crToCoord(editor.range.left, editor.range.top) + ":" +
+ SocialCalc.crToCoord(editor.range.right, editor.range.bottom);
+ }
+ else {
+ ele.value = editor.ecell.coord;
+ }
+ }
+
+SocialCalc.SpreadsheetControlNamesOnunclick = function(s, t) {
+ delete s.editor.RangeChangeCallback.names;
+ delete s.editor.MoveECellCallback.names;
+ }
+
+SocialCalc.SpreadsheetControlNamesSetValue = function() {
+ var s = SocialCalc.GetSpreadsheetControlObject();
+ document.getElementById(s.idPrefix+"namesvalue").value = document.getElementById(s.idPrefix+"namesrangeproposal").value;
+ SocialCalc.KeyboardFocus();
+ }
+
+SocialCalc.SpreadsheetControlNamesSave = function() {
+ var s = SocialCalc.GetSpreadsheetControlObject();
+ var name = document.getElementById(s.idPrefix+"namesname").value;
+ SocialCalc.SetTab(s.tabs[0].name); // return to first tab
+ SocialCalc.KeyboardFocus();
+ if (name != "") {
+ s.ExecuteCommand("name define "+name+" "+document.getElementById(s.idPrefix+"namesvalue").value+"\n"+
+ "name desc "+name+" "+document.getElementById(s.idPrefix+"namesdesc").value);
+ }
+ }
+
+SocialCalc.SpreadsheetControlNamesDelete = function() {
+ var s = SocialCalc.GetSpreadsheetControlObject();
+ var name = document.getElementById(s.idPrefix+"namesname").value;
+ SocialCalc.SetTab(s.tabs[0].name); // return to first tab
+ SocialCalc.KeyboardFocus();
+ if (name != "") {
+ s.ExecuteCommand("name delete "+name);
+// document.getElementById(s.idPrefix+"namesname").value = "";
+// document.getElementById(s.idPrefix+"namesvalue").value = "";
+// document.getElementById(s.idPrefix+"namesdesc").value = "";
+// SocialCalc.SpreadsheetControlNamesFillNameList();
+ }
+ SocialCalc.KeyboardFocus();
+ }
+
+// Clipboard
+
+SocialCalc.SpreadsheetControlClipboardOnclick = function(s, t) {
+ var s = SocialCalc.GetSpreadsheetControlObject();
+ clipele = document.getElementById(s.idPrefix+"clipboardtext");
+ document.getElementById(s.idPrefix+"clipboardformat-tab").checked = true;
+ clipele.value = SocialCalc.ConvertSaveToOtherFormat(SocialCalc.Clipboard.clipboard, "tab");
+ return;
+ }
+
+SocialCalc.SpreadsheetControlClipboardFormat = function(which) {
+ var s = SocialCalc.GetSpreadsheetControlObject();
+ clipele = document.getElementById(s.idPrefix+"clipboardtext");
+ clipele.value = SocialCalc.ConvertSaveToOtherFormat(SocialCalc.Clipboard.clipboard, which);
+ }
+
+SocialCalc.SpreadsheetControlClipboardLoad = function() {
+ var s = SocialCalc.GetSpreadsheetControlObject();
+ var savetype = "tab";
+ SocialCalc.SetTab(s.tabs[0].name); // return to first tab
+ SocialCalc.KeyboardFocus();
+ if (document.getElementById(s.idPrefix+"clipboardformat-csv").checked) {
+ savetype = "csv";
+ }
+ else if (document.getElementById(s.idPrefix+"clipboardformat-scsave").checked) {
+ savetype = "scsave";
+ }
+ s.editor.EditorScheduleSheetCommands("loadclipboard "+
+ SocialCalc.encodeForSave(
+ SocialCalc.ConvertOtherFormatToSave(document.getElementById(s.idPrefix+"clipboardtext").value, savetype)));
+ }
+
+SocialCalc.SpreadsheetControlClipboardClear = function() {
+ var s = SocialCalc.GetSpreadsheetControlObject();
+ var clipele = document.getElementById(s.idPrefix+"clipboardtext");
+ clipele.value = "";
+ s.editor.EditorScheduleSheetCommands("clearclipboard");
+ clipele.focus();
+ }
+
+SocialCalc.SpreadsheetControlClipboardExport = function() {
+ var s = SocialCalc.GetSpreadsheetControlObject();
+ if (s.ExportCallback) {
+ s.ExportCallback(s);
+ }
+ SocialCalc.SetTab(s.tabs[0].name); // return to first tab
+ SocialCalc.KeyboardFocus();
+ }
+
+// Settings
+
+SocialCalc.SpreadsheetControlSettingsSwitch = function(target) {
+ SocialCalc.SettingControlReset();
+ var s = SocialCalc.GetSpreadsheetControlObject();
+ var sheettable = document.getElementById(s.idPrefix+"sheetsettingstable");
+ var celltable = document.getElementById(s.idPrefix+"cellsettingstable");
+ var sheettoolbar = document.getElementById(s.idPrefix+"sheetsettingstoolbar");
+ var celltoolbar = document.getElementById(s.idPrefix+"cellsettingstoolbar");
+ if (target=="sheet") {
+ sheettable.style.display = "block";
+ celltable.style.display = "none";
+ sheettoolbar.style.display = "block";
+ celltoolbar.style.display = "none";
+ SocialCalc.SettingsControlSetCurrentPanel(s.views.settings.values.sheetspanel);
+ }
+ else {
+ sheettable.style.display = "none";
+ celltable.style.display = "block";
+ sheettoolbar.style.display = "none";
+ celltoolbar.style.display = "block";
+ SocialCalc.SettingsControlSetCurrentPanel(s.views.settings.values.cellspanel);
+ }
+ }
+
+SocialCalc.SettingsControlSave = function(target) {
+ var range, cmdstr;
+ var s = SocialCalc.GetSpreadsheetControlObject();
+ var sc = SocialCalc.SettingsControls;
+ var panelobj = sc.CurrentPanel;
+ var attribs = SocialCalc.SettingsControlUnloadPanel(panelobj);
+
+ SocialCalc.SetTab(s.tabs[0].name); // return to first tab
+ SocialCalc.KeyboardFocus();
+
+ if (target=="sheet") {
+ cmdstr = s.sheet.DecodeSheetAttributes(attribs);
+ }
+ else if (target=="cell") {
+ if (s.editor.range.hasrange) {
+ range = SocialCalc.crToCoord(s.editor.range.left, s.editor.range.top) + ":" +
+ SocialCalc.crToCoord(s.editor.range.right, s.editor.range.bottom);
+ }
+ cmdstr = s.sheet.DecodeCellAttributes(s.editor.ecell.coord, attribs, range);
+ }
+ else { // Cancel
+ }
+ if (cmdstr) {
+ s.editor.EditorScheduleSheetCommands(cmdstr);
+ }
+ }
+
+///////////////////////
+//
+// SAVE / LOAD ROUTINES
+//
+///////////////////////
+
+//
+// result = SocialCalc.SpreadsheetControlCreateSpreadsheetSave(spreadsheet)
+//
+// Saves the spreadsheet's sheet data, editor settings, and audit trail (redo stack).
+// The serialized data strings are concatenated together in multi-part MIME format.
+// The first part lists the types of the subsequent parts (e.g., "sheet", "editor", and "audit")
+// in this format:
+// # comments
+// version:1.0
+// part:type1
+// part:type2
+// ...
+//
+
+SocialCalc.SpreadsheetControlCreateSpreadsheetSave = function(spreadsheet) {
+
+ var result;
+
+ result = "socialcalc:version:1.0\n" +
+ "MIME-Version: 1.0\nContent-Type: multipart/mixed; boundary="+
+ spreadsheet.multipartBoundary + "\n" +
+ "--" + spreadsheet.multipartBoundary + "\nContent-type: text/plain; charset=UTF-8\n\n" +
+ "# SocialCalc Spreadsheet Control Save\nversion:1.0\npart:sheet\npart:edit\npart:audit\n" +
+ "--" + spreadsheet.multipartBoundary + "\nContent-type: text/plain; charset=UTF-8\n\n" +
+ spreadsheet.CreateSheetSave() +
+ "--" + spreadsheet.multipartBoundary + "\nContent-type: text/plain; charset=UTF-8\n\n" +
+ spreadsheet.editor.SaveEditorSettings() +
+ "--" + spreadsheet.multipartBoundary + "\nContent-type: text/plain; charset=UTF-8\n\n" +
+ spreadsheet.sheet.CreateAuditString() +
+ "--" + spreadsheet.multipartBoundary + "--\n";
+
+ return result;
+
+ }
+
+
+//
+// parts = SocialCalc.SpreadsheetControlDecodeSpreadsheetSave(spreadsheet, str)
+//
+// Separates the parts from a spreadsheet save string, returning an object with the sub-strings.
+//
+// {type1: {start: startpos, end: endpos}, type2:...}
+//
+
+SocialCalc.SpreadsheetControlDecodeSpreadsheetSave = function(spreadsheet, str) {
+
+ var pos1, mpregex, searchinfo, boundary, boundaryregex, blanklineregex, start, ending, lines, i, lines, p, pnun;
+ var parts = {};
+ var partlist = [];
+
+ pos1 = str.search(/^MIME-Version:\s1\.0/mi);
+ if (pos1 < 0){
+ return parts;
+ }
+
+ mpregex = /^Content-Type:\s*multipart\/mixed;\s*boundary=(\S+)/mig;
+ mpregex.lastIndex = pos1;
+
+ searchinfo = mpregex.exec(str);
+ if (mpregex.lastIndex <= 0){
+ return parts;
+ }
+ boundary = searchinfo[1];
+
+ boundaryregex = new RegExp("^--"+boundary+"(?:\r\n|\n)", "mg");
+ boundaryregex.lastIndex = mpregex.lastIndex;
+
+ searchinfo = boundaryregex.exec(str); // find header top boundary
+ blanklineregex = /(?:\r\n|\n)(?:\r\n|\n)/gm;
+ blanklineregex.lastIndex = boundaryregex.lastIndex;
+ searchinfo = blanklineregex.exec(str); // skip to after blank line
+ if (!searchinfo){
+ return parts;
+ }
+ start = blanklineregex.lastIndex;
+ boundaryregex.lastIndex = start;
+ searchinfo = boundaryregex.exec(str); // find end of header
+ if (!searchinfo){
+ return parts;
+ }
+ ending = searchinfo.index;
+
+ lines = str.substring(start, ending).split(/\r\n|\n/); // get header as lines
+ for (i=0;i<lines.length;i++) {
+ line=lines[i];
+ p = line.split(":");
+ switch (p[0]) {
+ case "version":
+ break;
+ case "part":
+ partlist.push(p[1]);
+ break;
+ }
+ }
+
+ for (pnum=0; pnum<partlist.length; pnum++) { // get each part
+ blanklineregex.lastIndex = ending;
+ searchinfo = blanklineregex.exec(str); // find blank line ending mime-part header
+ if (!searchinfo) return parts;
+ start = blanklineregex.lastIndex;
+ if (pnum==partlist.length-1) { // last one has different boundary
+ boundaryregex = new RegExp("^--"+boundary+"--$", "mg");
+ }
+ boundaryregex.lastIndex = start;
+ searchinfo = boundaryregex.exec(str); // find ending boundary
+ if (!searchinfo) return parts;
+ ending = searchinfo.index;
+ parts[partlist[pnum]] = {start: start, end: ending}; // return position within full string
+ }
+
+ return parts;
+
+ }
+
+
+/*
+* SettingsControls
+*
+* Each settings panel has an object in the following form:
+*
+* {ctrl-name1: {setting: setting-nameA, type: ctrl-type, id: id-component},
+* ctrl-name2: {setting: setting-nameB, type: ctrl-type, id: id-component, initialdata: optional-initialdata-override},
+* ...}
+*
+* The ctrl-types are names that correspond to:
+*
+* SocialCalc.SettingsControls.Controls = {
+* ctrl-type1: {
+* SetValue: function(panel-obj, ctrl-name, {def: true/false, val: value}) {...;},
+* ColorValues: if true, Onchanged converts between hex and RGB
+* GetValue: function(panel-obj, ctrl-name) {...return {def: true/false, val: value};},
+* Initialize: function(panel-obj, ctrl-name) {...;}, // used to fill dropdowns, etc.
+* InitialData: control-dependent, // used by Initialize (if no panel ctrlname.initialdata)
+* OnReset: function(ctrl-name) {...;}, // called to put down popups, etc.
+* ChangedCallback: function(ctrl-name) {...;} // if not null, called by control when user changes value
+* }
+*
+*/
+
+SocialCalc.SettingsControls = {
+ Controls: {},
+ CurrentPanel: null // panel object to search on events
+ };
+
+//
+// SocialCalc.SettingsControlSetCurrentPanel(panel-object)
+//
+
+SocialCalc.SettingsControlSetCurrentPanel = function(panelobj) {
+
+ SocialCalc.SettingsControls.CurrentPanel = panelobj;
+
+ SocialCalc.SettingsControls.PopupChangeCallback({panelobj: panelobj}, "", null);
+
+ }
+
+
+//
+// SocialCalc.SettingsControlInitializePanel(panel-object)
+//
+
+SocialCalc.SettingsControlInitializePanel = function(panelobj) {
+
+ var ctrlname;
+ var sc = SocialCalc.SettingsControls;
+
+ for (ctrlname in panelobj) {
+ if (ctrlname=="name") continue;
+ ctrl = sc.Controls[panelobj[ctrlname].type];
+ if (ctrl && ctrl.Initialize) ctrl.Initialize(panelobj, ctrlname);
+ }
+
+ }
+
+
+//
+// SocialCalc.SettingsControlLoadPanel(panel-object, attribs)
+//
+
+SocialCalc.SettingsControlLoadPanel = function(panelobj, attribs) {
+
+ var ctrlname;
+ var sc = SocialCalc.SettingsControls;
+
+ for (ctrlname in panelobj) {
+ if (ctrlname=="name") continue;
+ ctrl = sc.Controls[panelobj[ctrlname].type];
+ if (ctrl && ctrl.SetValue) ctrl.SetValue(panelobj, ctrlname, attribs[panelobj[ctrlname].setting]);
+ }
+
+ }
+
+//
+// attribs = SocialCalc.SettingsControlUnloadPanel(panel-object)
+//
+
+SocialCalc.SettingsControlUnloadPanel = function(panelobj) {
+
+ var ctrlname;
+ var sc = SocialCalc.SettingsControls;
+ var attribs = {};
+
+ for (ctrlname in panelobj) {
+ if (ctrlname=="name") continue;
+ ctrl = sc.Controls[panelobj[ctrlname].type];
+ if (ctrl && ctrl.GetValue) attribs[panelobj[ctrlname].setting] = ctrl.GetValue(panelobj, ctrlname);
+ }
+
+ return attribs;
+
+ }
+
+//
+// SocialCalc.SettingsControls.PopupChangeCallback
+//
+
+SocialCalc.SettingsControls.PopupChangeCallback = function(attribs, id, value) {
+
+ var sc = SocialCalc.Constants;
+
+ var ele = document.getElementById("sample-text");
+
+ if (!ele || !attribs || !attribs.panelobj) return;
+
+ var idPrefix = SocialCalc.CurrentSpreadsheetControlObject.idPrefix;
+
+ var c = attribs.panelobj.name == "cell" ? "c" : "";
+
+ var v, a, parts, str1, str2, i;
+
+ parts = sc.defaultCellLayout.match(/^padding.(\S+) (\S+) (\S+) (\S+).vertical.align.(\S+);$/) || [];
+
+ var cv = {color: ["textcolor"], backgroundColor: ["bgcolor", "#FFF"],
+ fontSize: ["fontsize", sc.defaultCellFontSize], fontFamily: ["fontfamily"],
+ paddingTop: ["padtop", parts[1]], paddingRight: ["padright", parts[2]],
+ paddingBottom: ["padbottom", parts[3]], paddingLeft: ["padleft", parts[4]],
+ verticalAlign: ["alignvert", parts[5]]};
+
+ for (a in cv) {
+ v = SocialCalc.Popup.GetValue(idPrefix+c+cv[a][0]) || cv[a][1] || "";
+ ele.style[a] = v;
+ }
+
+ if (c=="c") {
+ cv = {borderTop: "cbt", borderRight: "cbr", borderBottom: "cbb", borderLeft: "cbl"};
+ for (a in cv) {
+ v = SocialCalc.SettingsControls.BorderSideGetValue(attribs.panelobj, cv[a]);
+ ele.style[a] = v ? (v.val || "") : "";
+ }
+ v = SocialCalc.Popup.GetValue(idPrefix+"calignhoriz");
+ ele.style.textAlign = v || "left";
+ ele.childNodes[1].style.textAlign = v || "right";
+ }
+ else {
+ ele.style.border = "";
+ v = SocialCalc.Popup.GetValue(idPrefix+"textalignhoriz");
+ ele.style.textAlign = v || "left";
+ v = SocialCalc.Popup.GetValue(idPrefix+"numberalignhoriz");
+ ele.childNodes[1].style.textAlign = v || "right";
+ }
+
+ v = SocialCalc.Popup.GetValue(idPrefix+c+"fontlook");
+ parts = v ? (v.match(/^(\S+) (\S+)$/) || []) : [];
+ ele.style.fontStyle = parts[1] || "";
+ ele.style.fontWeight = parts[2] || "";
+
+ v = SocialCalc.Popup.GetValue(idPrefix+c+"formatnumber") || "General";
+ str1 = SocialCalc.FormatNumber.formatNumberWithFormat(9.8765, v, "");
+ str2 = SocialCalc.FormatNumber.formatNumberWithFormat(-1234.5, v, "");
+ if (str2 != "??-???-??&nbsp;??:??:??") { // not bad date from negative number
+ str1 += "<br>"+str2;
+ }
+
+ ele.childNodes[1].innerHTML = str1;
+
+ }
+
+//
+// PopupList Control
+//
+
+SocialCalc.SettingsControls.PopupListSetValue = function(panelobj, ctrlname, value) {
+
+ if (!value) {alert(ctrlname+" no value"); return;}
+
+ var sp = SocialCalc.Popup;
+
+ if (!value.def) {
+ sp.SetValue(panelobj[ctrlname].id, value.val);
+ }
+ else {
+ sp.SetValue(panelobj[ctrlname].id, "");
+ }
+
+ }
+
+//
+// SocialCalc.SettingsControls.PopupListGetValue
+//
+
+SocialCalc.SettingsControls.PopupListGetValue = function(panelobj, ctrlname) {
+
+ var ctl = panelobj[ctrlname];
+ if (!ctl) return null;
+
+ var value = SocialCalc.Popup.GetValue(ctl.id);
+ if (value) {
+ return {def: false, val: value};
+ }
+ else {
+ return {def: true, val: 0};
+ }
+
+ }
+
+//
+// SocialCalc.SettingsControls.PopupListInitialize
+//
+
+SocialCalc.SettingsControls.PopupListInitialize = function(panelobj, ctrlname) {
+
+ var i, val, pos, otext;
+ var sc = SocialCalc.SettingsControls;
+ var initialdata = panelobj[ctrlname].initialdata || sc.Controls[panelobj[ctrlname].type].InitialData || "";
+ initialdata = SocialCalc.LocalizeSubstrings(initialdata);
+ var optionvals = initialdata.split(/\|/);
+
+ var options = [];
+
+ for (i=0; i<(optionvals.length||0); i++) {
+ val = optionvals[i];
+ pos = val.indexOf(":");
+ otext = val.substring(0, pos);
+ if (otext.indexOf("\\")!=-1) { // escape any colons
+ otext = otext.replace(/\\c/g,":");
+ otext = otext.replace(/\\b/g,"\\");
+
+ }
+ otext = SocialCalc.special_chars(otext);
+ if (otext == "[custom]") {
+ options[i] = {o: SocialCalc.Constants.s_PopupListCustom, v: val.substring(pos+1), a:{custom: true}};
+ }
+ else if (otext == "[cancel]") {
+ options[i] = {o: SocialCalc.Constants.s_PopupListCancel, v: "", a:{cancel: true}};
+ }
+ else if (otext == "[break]") {
+ options[i] = {o: "-----", v: "", a:{skip: true}};
+ }
+ else if (otext == "[newcol]") {
+ options[i] = {o: "", v: "", a:{newcol: true}};
+ }
+ else {
+ options[i] = {o: otext, v: val.substring(pos+1)};
+ }
+ }
+
+ SocialCalc.Popup.Create("List", panelobj[ctrlname].id, {});
+ SocialCalc.Popup.Initialize(panelobj[ctrlname].id,
+ {options: options,
+ attribs:{changedcallback: SocialCalc.SettingsControls.PopupChangeCallback, panelobj: panelobj}});
+
+ }
+
+
+//
+// SocialCalc.SettingsControls.PopupListReset
+//
+
+SocialCalc.SettingsControls.PopupListReset = function(ctrlname) {
+
+ SocialCalc.Popup.Reset("List");
+
+ }
+
+SocialCalc.SettingsControls.Controls.PopupList = {
+ SetValue: SocialCalc.SettingsControls.PopupListSetValue,
+ GetValue: SocialCalc.SettingsControls.PopupListGetValue,
+ Initialize: SocialCalc.SettingsControls.PopupListInitialize,
+ OnReset: SocialCalc.SettingsControls.PopupListReset,
+ ChangedCallback: null
+ }
+
+//
+// ColorChooser Control
+//
+
+SocialCalc.SettingsControls.ColorChooserSetValue = function(panelobj, ctrlname, value) {
+
+ if (!value) {alert(ctrlname+" no value"); return;}
+
+ var sp = SocialCalc.Popup;
+
+ if (!value.def) {
+ sp.SetValue(panelobj[ctrlname].id, value.val);
+ }
+ else {
+ sp.SetValue(panelobj[ctrlname].id, "");
+ }
+
+ }
+
+//
+// SocialCalc.SettingsControls.ColorChooserGetValue
+//
+
+SocialCalc.SettingsControls.ColorChooserGetValue = function(panelobj, ctrlname) {
+
+ var value = SocialCalc.Popup.GetValue(panelobj[ctrlname].id);
+ if (value) {
+ return {def: false, val: value};
+ }
+ else {
+ return {def: true, val: 0};
+ }
+
+ }
+
+//
+// SocialCalc.SettingsControls.ColorChooserInitialize
+//
+
+SocialCalc.SettingsControls.ColorChooserInitialize = function(panelobj, ctrlname) {
+
+ var i, val, pos, otext;
+ var sc = SocialCalc.SettingsControls;
+
+ SocialCalc.Popup.Create("ColorChooser", panelobj[ctrlname].id, {});
+ SocialCalc.Popup.Initialize(panelobj[ctrlname].id,
+ {attribs:{title: "&nbsp;", moveable: true, width: "106px",
+ changedcallback: SocialCalc.SettingsControls.PopupChangeCallback, panelobj: panelobj}});
+
+ }
+
+
+//
+// SocialCalc.SettingsControls.ColorChooserReset
+//
+
+SocialCalc.SettingsControls.ColorChooserReset = function(ctrlname) {
+
+ SocialCalc.Popup.Reset("ColorChooser");
+
+ }
+
+SocialCalc.SettingsControls.Controls.ColorChooser = {
+ SetValue: SocialCalc.SettingsControls.ColorChooserSetValue,
+ GetValue: SocialCalc.SettingsControls.ColorChooserGetValue,
+ Initialize: SocialCalc.SettingsControls.ColorChooserInitialize,
+ OnReset: SocialCalc.SettingsControls.ColorChooserReset,
+ ChangedCallback: null
+ }
+
+
+//
+// SocialCalc.SettingsControls.BorderSideSetValue
+//
+
+SocialCalc.SettingsControls.BorderSideSetValue = function(panelobj, ctrlname, value) {
+
+ var sc = SocialCalc.SettingsControls;
+ var ele, found, idname, parts;
+ var idstart = panelobj[ctrlname].id;
+
+ if (!value) {alert(ctrlname+" no value"); return;}
+
+ ele = document.getElementById(idstart+"-onoff-bcb"); // border checkbox
+ if (!ele) return;
+
+ if (value.val) { // border does not use default: it looks only to the value currently
+ ele.checked = true;
+ ele.value = value.val;
+ parts = value.val.match(/(\S+)\s+(\S+)\s+(\S.+)/);
+ idname = idstart+"-color";
+ SocialCalc.Popup.SetValue(idname, parts[3]);
+ SocialCalc.Popup.SetDisabled(idname, false);
+ }
+ else {
+ ele.checked = false;
+ ele.value = value.val;
+ idname = idstart+"-color";
+ SocialCalc.Popup.SetValue(idname, "");
+ SocialCalc.Popup.SetDisabled(idname, true);
+ }
+
+ }
+
+//
+// SocialCalc.SettingsControls.BorderSideGetValue
+//
+
+SocialCalc.SettingsControls.BorderSideGetValue = function(panelobj, ctrlname) {
+
+ var sc = SocialCalc.SettingsControls;
+ var ele, value;
+ var idstart = panelobj[ctrlname].id;
+
+ ele = document.getElementById(idstart+"-onoff-bcb"); // border checkbox
+ if (!ele) return;
+
+
+ if (ele.checked) { // on
+ value = SocialCalc.Popup.GetValue(idstart+"-color");
+ value = "1px solid " + (value || "rgb(0,0,0)");
+ return {def: false, val: value};
+ }
+ else { // off
+ return {def: false, val: ""};
+ }
+
+ }
+
+//
+// SocialCalc.SettingsControls.BorderSideInitialize
+//
+
+SocialCalc.SettingsControls.BorderSideInitialize = function(panelobj, ctrlname) {
+
+ var sc = SocialCalc.SettingsControls;
+ var idstart = panelobj[ctrlname].id;
+
+ SocialCalc.Popup.Create("ColorChooser", idstart+"-color", {});
+ SocialCalc.Popup.Initialize(idstart+"-color",
+ {attribs:{title: "&nbsp;", width: "106px", moveable: true,
+ changedcallback: SocialCalc.SettingsControls.PopupChangeCallback, panelobj: panelobj}});
+
+ }
+
+
+//
+// SocialCalc.SettingsControlOnchangeBorder = function(ele)
+//
+
+SocialCalc.SettingsControlOnchangeBorder = function(ele) {
+
+ var idname, value, found, ele2;
+ var sc = SocialCalc.SettingsControls;
+ var panelobj = sc.CurrentPanel;
+
+ var nameparts = ele.id.match(/(^.*\-)(\w+)\-(\w+)\-(\w+)$/);
+ if (!nameparts) return;
+ var prefix = nameparts[1];
+ var ctrlname = nameparts[2];
+ var ctrlsubid = nameparts[3]
+ var ctrlidsuffix = nameparts[4];
+ var ctrltype = panelobj[ctrlname].type;
+
+ switch (ctrlidsuffix) {
+ case "bcb": // border checkbox
+ if (ele.checked) {
+ sc.Controls[ctrltype].SetValue(sc.CurrentPanel, ctrlname, {def: false, val: ele.value || "1px solid rgb(0,0,0)"});
+ }
+ else {
+ sc.Controls[ctrltype].SetValue(sc.CurrentPanel, ctrlname, {def: false, val: ""});
+ }
+ break;
+ }
+
+ }
+
+
+SocialCalc.SettingsControls.Controls.BorderSide = {
+ SetValue: SocialCalc.SettingsControls.BorderSideSetValue,
+ GetValue: SocialCalc.SettingsControls.BorderSideGetValue,
+ OnClick: SocialCalc.SettingsControls.ColorComboOnClick,
+ Initialize: SocialCalc.SettingsControls.BorderSideInitialize,
+ InitialData: {thickness: "1 pixel:1px", style: "Solid:solid"},
+ ChangedCallback: null
+ }
+
+
+SocialCalc.SettingControlReset = function() {
+
+ var sc = SocialCalc.SettingsControls;
+ var ctrlname;
+
+ for (ctrlname in sc.Controls) {
+ if (sc.Controls[ctrlname].OnReset) sc.Controls[ctrlname].OnReset(ctrlname);
+ }
+ }
+
diff --git a/web/socialcalctableeditor.js b/web/socialcalctableeditor.js
new file mode 100644
index 0000000..fbb0a1a
--- /dev/null
+++ b/web/socialcalctableeditor.js
@@ -0,0 +1,5127 @@
+//
+// SocialCalcTableEditor
+//
+/*
+// The code module of the SocialCalc package that displays a scrolling grid with panes
+// and handles keyboard and mouse I/O.
+//
+// (c) Copyright 2008 Socialtext, Inc.
+// All Rights Reserved.
+//
+*/
+
+/*
+
+LEGAL NOTICES REQUIRED BY THE COMMON PUBLIC ATTRIBUTION LICENSE:
+
+EXHIBIT A. Common Public Attribution License Version 1.0.
+
+The contents of this file are subject to the Common Public Attribution License Version 1.0 (the
+"License"); you may not use this file except in compliance with the License. You may obtain a copy
+of the License at http://socialcalc.org. The License is based on the Mozilla Public License Version 1.1 but
+Sections 14 and 15 have been added to cover use of software over a computer network and provide for
+limited attribution for the Original Developer. In addition, Exhibit A has been modified to be
+consistent with Exhibit B.
+
+Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+KIND, either express or implied. See the License for the specific language governing rights and
+limitations under the License.
+
+The Original Code is SocialCalc JavaScript TableEditor.
+
+The Original Developer is the Initial Developer.
+
+The Initial Developer of the Original Code is Socialtext, Inc. All portions of the code written by
+Socialtext, Inc., are Copyright (c) Socialtext, Inc. All Rights Reserved.
+
+Contributor: Dan Bricklin.
+
+
+EXHIBIT B. Attribution Information
+
+When the TableEditor is producing and/or controlling the display the Graphic Image must be
+displayed on the screen visible to the user in a manner comparable to that in the
+Original Code. The Attribution Phrase must be displayed as a "tooltip" or "hover-text" for
+that image. The image must be linked to the Attribution URL so as to access that page
+when clicked. If the user interface includes a prominent "about" display which includes
+factual prominent attribution in a form similar to that in the "about" display included
+with the Original Code, including Socialtext copyright notices and URLs, then the image
+need not be linked to the Attribution URL but the "tool-tip" is still required.
+
+Attribution Copyright Notice:
+
+ Copyright (C) 2008 Socialtext, Inc.
+ All Rights Reserved.
+
+Attribution Phrase (not exceeding 10 words): SocialCalc
+
+Attribution URL: http://www.socialcalc.org/xoattrib
+
+Graphic Image: The contents of the sc-logo.gif file in the Original Code or
+a suitable replacement from http://www.socialcalc.org/licenses specified as
+being for SocialCalc.
+
+Display of Attribution Information is required in Larger Works which are defined
+in the CPAL as a work which combines Covered Code or portions thereof with code
+not governed by the terms of the CPAL.
+
+*/
+
+//
+// Some of the other files in the SocialCalc package are licensed under
+// different licenses. Please note the licenses of the modules you use.
+//
+// Code History:
+//
+// Initially coded by Dan Bricklin of Software Garden, Inc., for Socialtext, Inc.
+// Based in part on the SocialCalc 1.1.0 code written in Perl.
+// The SocialCalc 1.1.0 code was:
+// Portions (c) Copyright 2005, 2006, 2007 Software Garden, Inc.
+// All Rights Reserved.
+// Portions (c) Copyright 2007 Socialtext, Inc.
+// All Rights Reserved.
+// The Perl SocialCalc started as modifications to the wikiCalc(R) program, version 1.0.
+// wikiCalc 1.0 was written by Software Garden, Inc.
+// Unless otherwise specified, referring to "SocialCalc" in comments refers to this
+// JavaScript version of the code, not the SocialCalc Perl code.
+//
+
+/*
+
+See the comments in the main SocialCalc code module file of the SocialCalc package.
+
+*/
+
+ var SocialCalc;
+ if (!SocialCalc) { // created here, too, in case load order is wrong, but main routines are required
+ SocialCalc = {};
+ }
+
+// *************************************
+//
+// Table Editor class:
+//
+// *************************************
+
+// Constructor:
+
+SocialCalc.TableEditor = function(context) {
+
+ var scc = SocialCalc.Constants;
+
+ // Properties:
+
+ this.context = context; // editing context
+ this.toplevel = null; // top level HTML element for this table editor
+ this.fullgrid = null; // rendered editing context
+
+ this.width = null;
+ this.tablewidth = null;
+ this.height = null;
+ this.tableheight = null;
+
+ this.inputBox = null;
+ this.inputEcho = null;
+ this.verticaltablecontrol = null;
+ this.horizontaltablecontrol = null;
+
+ this.logo = null;
+
+ // Dynamic properties:
+
+ this.timeout = null; // if non-null, timer id for position calculations
+ this.busy = false; // true when executing command, calculating, etc.
+ this.ensureecell = false; // if true, ensure ecell is visible after timeout
+ this.deferredCommands = []; // commands to execute after busy
+
+ this.gridposition = null; // screen coords of full grid
+ this.headposition = null; // screen coords of upper left of grid within header rows
+ this.firstscrollingrow = null; // row number of top row in last (the scrolling) pane
+ this.firstscrollingrowtop = null; // position of top row in last (the scrolling) pane
+ this.lastnonscrollingrow = null; // row number of last displayed row in last non-scrolling
+ // pane, or zero (for thumb position calculations)
+ this.lastvisiblerow = null; // used for paging down
+ this.firstscrollingcol = null; // column number of top col in last (the scrolling) pane
+ this.firstscrollingcolleft = null; // position of top col in last (the scrolling) pane
+ this.lastnonscrollingcol = null; // col number of last displayed column in last non-scrolling
+ // pane, or zero (for thumb position calculations)
+ this.lastvisiblecol = null; // used for paging right
+
+ this.rowpositions = []; // screen positions of the top of some rows
+ this.colpositions = []; // screen positions of the left side of some rows
+ this.rowheight = []; // size in pixels of each row when last checked, or null/undefined, for page up
+ this.colwidth = []; // size in pixels of each column when last checked, or null/undefined, for page left
+
+ this.ecell = null; // either null or {coord: c, row: r, col: c}
+ this.state = "start"; // the keyboard states: see EditorProcessKey
+
+ this.workingvalues = {}; // values used during keyboard editing, etc.
+
+ // Constants:
+
+ this.imageprefix = scc.defaultImagePrefix; // URL prefix for images (e.g., "/images/sc")
+ this.idPrefix = scc.defaultTableEditorIDPrefix;
+ this.pageUpDnAmount = scc.defaultPageUpDnAmount; // number of rows to move cursor on PgUp/PgDn keys (numeric)
+
+ // Callbacks
+
+ // recalcFunction: if present, function(editor) {...}, called to do a recalc
+ // Default (sheet.RecalcSheet) does all the right stuff.
+
+ this.recalcFunction = function(editor) {
+ if (editor.context.sheetobj.RecalcSheet) {
+ editor.context.sheetobj.RecalcSheet(SocialCalc.EditorSheetStatusCallback, editor);
+ }
+ else return null;
+ };
+
+ // ctrlkeyFunction: if present, function(editor, charname) {...}, called to handle ctrl-V, etc., at top level
+ // Returns true (pass through for continued processing) or false (stop processing this key).
+
+ this.ctrlkeyFunction = function(editor, charname) {
+
+ var ta, cell, position, cmd, sel, cliptext;
+
+ switch (charname) {
+ case "[ctrl-c]":
+ case "[ctrl-x]":
+ ta = editor.pasteTextarea;
+ ta.value = "";
+ cell=SocialCalc.GetEditorCellElement(editor, editor.ecell.row, editor.ecell.col);
+ if (cell) {
+ position = SocialCalc.GetElementPosition(cell.element);
+ ta.style.left = (position.left-1)+"px";
+ ta.style.top = (position.top-1)+"px";
+ }
+ if (editor.range.hasrange) {
+ sel = SocialCalc.crToCoord(editor.range.left, editor.range.top)+
+ ":"+SocialCalc.crToCoord(editor.range.right, editor.range.bottom);
+ }
+ else {
+ sel = editor.ecell.coord;
+ }
+
+ // get what to copy to clipboard
+ cliptext = SocialCalc.ConvertSaveToOtherFormat(SocialCalc.CreateSheetSave(editor.context.sheetobj, sel), "tab");
+
+ if (charname == "[ctrl-c]") {
+ cmd = "copy "+sel+" formulas";
+ }
+ else { // [ctrl-x]
+ cmd = "cut "+sel+" formulas";
+ }
+ editor.EditorScheduleSheetCommands(cmd); // queue up command to put on SocialCalc clipboard
+
+ ta.style.display = "block";
+ ta.value = cliptext; // must follow "block" setting for Webkit
+ ta.focus();
+ ta.select();
+ window.setTimeout(function() {
+ var s = SocialCalc.GetSpreadsheetControlObject();
+ if (!s) return;
+ var editor = s.editor;
+ var ta = editor.pasteTextarea;
+ ta.blur();
+ ta.style.display = "none";
+ SocialCalc.KeyboardFocus();
+ }, 200);
+
+ return true;
+
+ case "[ctrl-v]":
+ ta = editor.pasteTextarea;
+ ta.value = "";
+ cell=SocialCalc.GetEditorCellElement(editor, editor.ecell.row, editor.ecell.col);
+ if (cell) {
+ position = SocialCalc.GetElementPosition(cell.element);
+ ta.style.left = (position.left-1)+"px";
+ ta.style.top = (position.top-1)+"px";
+ }
+ ta.style.display = "block";
+ ta.value = ""; // must follow "block" setting for Webkit
+ ta.focus();
+ window.setTimeout(function() {
+ var s = SocialCalc.GetSpreadsheetControlObject();
+ if (!s) return;
+ var editor = s.editor;
+ var ta = editor.pasteTextarea;
+ var value = ta.value;
+ ta.blur();
+ ta.style.display = "none";
+ var cmd = "";
+ var clipstr = SocialCalc.ConvertSaveToOtherFormat(SocialCalc.Clipboard.clipboard, "tab");
+ value = value.replace(/\r\n/g, "\n");
+ // pastes SocialCalc clipboard if did a Ctrl-C and contents still the same
+ // Webkit adds an extra blank line, so need to allow for that
+ if (value != clipstr && (value.length-clipstr.length!=1 || value.substring(0,value.length-1)!=clipstr)) {
+ cmd = "loadclipboard "+
+ SocialCalc.encodeForSave(SocialCalc.ConvertOtherFormatToSave(value, "tab")) + "\n";
+ }
+ var cr;
+ if (editor.range.hasrange) {
+ cr = SocialCalc.crToCoord(editor.range.left, editor.range.top);
+ }
+ else {
+ cr = editor.ecell.coord;
+ }
+ cmd += "paste "+cr+" formulas";
+ editor.EditorScheduleSheetCommands(cmd);
+ SocialCalc.KeyboardFocus();
+ }, 200);
+ return true;
+
+ case "[ctrl-z]":
+ editor.EditorScheduleSheetCommands("undo");
+ return false;
+
+ case "[ctrl-s]": // !!!! temporary hack
+ if (!SocialCalc.Constants.AllowCtrlS) break;
+ window.setTimeout(
+ function() {
+ var s = SocialCalc.GetSpreadsheetControlObject();
+ if (!s) return;
+ var editor = s.editor;
+ var sheet = editor.context.sheetobj;
+ var cell = sheet.GetAssuredCell(editor.ecell.coord);
+ var ntvf = cell.nontextvalueformat ? sheet.valueformats[cell.nontextvalueformat-0] || "" : "";
+ var newntvf = window.prompt("Advanced Feature:\n\nCustom Numeric Format or Command", ntvf);
+ if (newntvf != null) { // not cancelled
+ if (newntvf.match(/^cmd:/)) {
+ cmd = newntvf.substring(4); // execute as command
+ }
+ else {
+ if (editor.range.hasrange) {
+ sel = SocialCalc.crToCoord(editor.range.left, editor.range.top)+
+ ":"+SocialCalc.crToCoord(editor.range.right, editor.range.bottom);
+ }
+ else {
+ sel = editor.ecell.coord;
+ }
+ cmd = "set "+sel+" nontextvalueformat "+newntvf;
+ }
+ editor.EditorScheduleSheetCommands(cmd);
+ }
+ },
+ 200);
+ return false;
+
+ default:
+ break;
+ }
+ return true;
+ };
+
+ // Set sheet's status callback:
+
+ context.sheetobj.statuscallback = SocialCalc.EditorSheetStatusCallback;
+ context.sheetobj.statuscallbackparams = this; // this object: the table editor object
+
+
+ // StatusCallback: all values are called at appropriate times, add with unique name, delete when done
+ //
+ // Each value must be an object in the form of:
+ //
+ // func: function(editor, status, arg, params) {...},
+ // params: params value to call func with
+ //
+ // The values for status and arg are:
+ //
+ // all the SocialCalc RecalcSheet statuscallbacks, including:
+ //
+ // calccheckdone, calclist length
+ // calcorder, {coord: coord, total: celllist length, count: count}
+ // calcstep, {coord: coord, total: calclist length, count: count}
+ // calcfinished, time in milliseconds
+ //
+ // the command callbacks, like cmdstart and cmdend
+ // cmdendnorender
+ //
+ // calcstart, null
+ // moveecell, new ecell coord
+ // rangechange, "coord:coord" or "coord" or ""
+ // specialkey, keyname ("[esc]")
+ //
+
+ this.StatusCallback = {};
+
+
+ this.MoveECellCallback = {}; // all values are called with editor as arg; add with unique name, delete when done
+ this.RangeChangeCallback = {}; // all values are called with editor as arg; add with unique name, delete when done
+ this.SettingsCallbacks = {}; // See SocialCalc.SaveEditorSettings
+
+ // Set initial cursor
+
+ this.ecell = {coord: "A1", row: 1, col: 1};
+ context.highlights[this.ecell.coord] = "cursor";
+
+ // Initialize range data
+ // Range has at least hasrange (true/false).
+ // It may also have: anchorcoord, anchorrow, anchorcol, top, bottom, left, and right.
+
+ this.range = {hasrange: false};
+
+ // Initialize range2 data (used to show selections, such as for move)
+ // Range2 has at least hasrange (true/false).
+ // It may also have: top, bottom, left, and right.
+
+ this.range2 = {hasrange: false};
+
+ }
+
+// Methods:
+
+SocialCalc.TableEditor.prototype.CreateTableEditor = function(width, height) {return SocialCalc.CreateTableEditor(this, width, height);};
+SocialCalc.TableEditor.prototype.ResizeTableEditor = function(width, height) {return SocialCalc.ResizeTableEditor(this, width, height);};
+
+SocialCalc.TableEditor.prototype.SaveEditorSettings = function() {return SocialCalc.SaveEditorSettings(this);};
+SocialCalc.TableEditor.prototype.LoadEditorSettings = function(str, flags) {return SocialCalc.LoadEditorSettings(this, str, flags);};
+
+SocialCalc.TableEditor.prototype.EditorRenderSheet = function() {SocialCalc.EditorRenderSheet(this);};
+SocialCalc.TableEditor.prototype.EditorScheduleSheetCommands = function(cmdstr, ignoreundo) {SocialCalc.EditorScheduleSheetCommands(this, cmdstr, ignoreundo);};
+SocialCalc.TableEditor.prototype.ScheduleSheetCommands = function(cmdstr, saveundo) {
+ this.context.sheetobj.ScheduleSheetCommands(cmdstr, saveundo);
+ };
+SocialCalc.TableEditor.prototype.SheetUndo = function() {
+ this.context.sheetobj.SheetUndo();
+ };
+SocialCalc.TableEditor.prototype.SheetRedo = function() {
+ this.context.sheetobj.SheetRedo();
+ };
+SocialCalc.TableEditor.prototype.EditorStepSet = function(status, arg) {SocialCalc.EditorStepSet(this, status, arg);};
+SocialCalc.TableEditor.prototype.GetStatuslineString = function(status, arg, params) {return SocialCalc.EditorGetStatuslineString(this, status, arg, params);};
+
+SocialCalc.TableEditor.prototype.EditorMouseRegister = function() {return SocialCalc.EditorMouseRegister(this);};
+SocialCalc.TableEditor.prototype.EditorMouseUnregister = function() {return SocialCalc.EditorMouseUnregister(this);};
+SocialCalc.TableEditor.prototype.EditorMouseRange = function(coord) {return SocialCalc.EditorMouseRange(this, coord);};
+
+SocialCalc.TableEditor.prototype.EditorProcessKey = function(ch, e) {return SocialCalc.EditorProcessKey(this, ch, e);};
+SocialCalc.TableEditor.prototype.EditorAddToInput = function(str, prefix) {return SocialCalc.EditorAddToInput(this, str, prefix);};
+SocialCalc.TableEditor.prototype.DisplayCellContents = function() {return SocialCalc.EditorDisplayCellContents(this);};
+SocialCalc.TableEditor.prototype.EditorSaveEdit = function(text) {return SocialCalc.EditorSaveEdit(this, text);};
+SocialCalc.TableEditor.prototype.EditorApplySetCommandsToRange = function(cmdline, type) {return SocialCalc.EditorApplySetCommandsToRange(this, cmdline, type);};
+
+SocialCalc.TableEditor.prototype.MoveECellWithKey = function(ch) {return SocialCalc.MoveECellWithKey(this, ch);};
+SocialCalc.TableEditor.prototype.MoveECell = function(newcell) {return SocialCalc.MoveECell(this, newcell);};
+SocialCalc.TableEditor.prototype.ReplaceCell = function(cell, row, col) {SocialCalc.ReplaceCell(this, cell, row, col);};
+SocialCalc.TableEditor.prototype.UpdateCellCSS = function(cell, row, col) {SocialCalc.UpdateCellCSS(this, cell, row, col);};
+SocialCalc.TableEditor.prototype.SetECellHeaders = function(selected) {SocialCalc.SetECellHeaders(this, selected);};
+SocialCalc.TableEditor.prototype.EnsureECellVisible = function() {SocialCalc.EnsureECellVisible(this);};
+SocialCalc.TableEditor.prototype.RangeAnchor = function(coord) {SocialCalc.RangeAnchor(this, coord);};
+SocialCalc.TableEditor.prototype.RangeExtend = function(coord) {SocialCalc.RangeExtend(this, coord);};
+SocialCalc.TableEditor.prototype.RangeRemove = function() {SocialCalc.RangeRemove(this);};
+SocialCalc.TableEditor.prototype.Range2Remove = function() {SocialCalc.Range2Remove(this);};
+
+SocialCalc.TableEditor.prototype.FitToEditTable = function() {SocialCalc.FitToEditTable(this);};
+SocialCalc.TableEditor.prototype.CalculateEditorPositions = function() {SocialCalc.CalculateEditorPositions(this);};
+SocialCalc.TableEditor.prototype.ScheduleRender = function() {SocialCalc.ScheduleRender(this);};
+SocialCalc.TableEditor.prototype.DoRenderStep = function() {SocialCalc.DoRenderStep(this);};
+SocialCalc.TableEditor.prototype.SchedulePositionCalculations = function() {SocialCalc.SchedulePositionCalculations(this);};
+SocialCalc.TableEditor.prototype.DoPositionCalculations = function() {SocialCalc.DoPositionCalculations(this);};
+SocialCalc.TableEditor.prototype.CalculateRowPositions = function(panenum, positions, sizes) {return SocialCalc.CalculateRowPositions(this, panenum, positions, sizes);};
+SocialCalc.TableEditor.prototype.CalculateColPositions = function(panenum, positions, sizes) {return SocialCalc.CalculateColPositions(this, panenum, positions, sizes);};
+
+SocialCalc.TableEditor.prototype.ScrollRelative = function(vertical, amount) {SocialCalc.ScrollRelative(this, vertical, amount);};
+SocialCalc.TableEditor.prototype.ScrollRelativeBoth = function(vamount, hamount) {SocialCalc.ScrollRelativeBoth(this, vamount, hamount);};
+SocialCalc.TableEditor.prototype.PageRelative = function(vertical, direction) {SocialCalc.PageRelative(this, vertical, direction);};
+SocialCalc.TableEditor.prototype.LimitLastPanes = function() {SocialCalc.LimitLastPanes(this);};
+
+SocialCalc.TableEditor.prototype.ScrollTableUpOneRow = function() {return SocialCalc.ScrollTableUpOneRow(this);};
+SocialCalc.TableEditor.prototype.ScrollTableDownOneRow = function() {return SocialCalc.ScrollTableDownOneRow(this);};
+SocialCalc.TableEditor.prototype.ScrollTableLeftOneCol = function() {return SocialCalc.ScrollTableLeftOneCol(this);};
+SocialCalc.TableEditor.prototype.ScrollTableRightOneCol = function() {return SocialCalc.ScrollTableRightOneCol(this);};
+
+// Functions:
+
+SocialCalc.CreateTableEditor = function(editor, width, height) {
+
+ var scc = SocialCalc.Constants;
+ var AssignID = SocialCalc.AssignID;
+
+ editor.toplevel = document.createElement("div");
+ editor.width = width;
+ editor.height = height;
+
+ editor.griddiv = document.createElement("div");
+ editor.tablewidth = width - scc.defaultTableControlThickness;
+ editor.tableheight = height - scc.defaultTableControlThickness;
+ editor.griddiv.style.width=editor.tablewidth+"px";
+ editor.griddiv.style.height=editor.tableheight+"px";
+ editor.griddiv.style.overflow="hidden";
+ editor.griddiv.style.cursor="default";
+ if (scc.cteGriddivClass) editor.griddiv.className = scc.cteGriddivClass;
+ AssignID(editor, editor.griddiv, "griddiv");
+
+ editor.FitToEditTable();
+
+ editor.EditorRenderSheet();
+
+ editor.griddiv.appendChild(editor.fullgrid);
+
+ editor.verticaltablecontrol = new SocialCalc.TableControl(editor, true, editor.tableheight);
+ editor.verticaltablecontrol.CreateTableControl();
+ AssignID(editor, editor.verticaltablecontrol.main, "tablecontrolv");
+
+ editor.horizontaltablecontrol = new SocialCalc.TableControl(editor, false, editor.tablewidth);
+ editor.horizontaltablecontrol.CreateTableControl();
+ AssignID(editor, editor.horizontaltablecontrol.main, "tablecontrolh");
+
+ var table, tbody, tr, td, img, anchor, ta;
+
+ table = document.createElement("table");
+ editor.layouttable = table;
+ table.cellSpacing = 0;
+ table.cellPadding = 0;
+ AssignID(editor, table, "layouttable");
+
+ tbody = document.createElement("tbody");
+ table.appendChild(tbody);
+
+ tr = document.createElement("tr");
+ tbody.appendChild(tr);
+ td = document.createElement("td");
+ td.appendChild(editor.griddiv);
+ tr.appendChild(td);
+ td = document.createElement("td");
+ td.appendChild(editor.verticaltablecontrol.main);
+ tr.appendChild(td);
+
+ tr = document.createElement("tr");
+ tbody.appendChild(tr);
+ td = document.createElement("td");
+ td.appendChild(editor.horizontaltablecontrol.main);
+ tr.appendChild(td);
+
+ td = document.createElement("td"); // logo display: Required by CPAL License for this code!
+ td.style.background="url("+editor.imageprefix+"logo.gif) no-repeat center center";
+ td.innerHTML = "<div style='cursor:pointer;font-size:1px;'><img src='"+editor.imageprefix+"1x1.gif' border='0' width='18' height='18'></div>";
+ tr.appendChild(td);
+ editor.logo = td;
+ AssignID(editor, editor.logo, "logo");
+ SocialCalc.TooltipRegister(td.firstChild.firstChild, "SocialCalc", null);
+
+ editor.toplevel.appendChild(editor.layouttable);
+
+ editor.inputEcho = new SocialCalc.InputEcho(editor);
+ AssignID(editor, editor.inputEcho.main, "inputecho");
+
+ ta = document.createElement("textarea"); // used for ctrl-c/ctrl-v where an invisible text area is needed
+ SocialCalc.setStyles(ta, "display:none;position:absolute;height:1px;width:1px;opacity:0;filter:alpha(opacity=0);");
+ ta.value = "";
+ editor.pasteTextarea = ta;
+ AssignID(editor, editor.pasteTextarea, "pastetextarea");
+
+ editor.toplevel.appendChild(editor.pasteTextarea);
+
+ SocialCalc.MouseWheelRegister(editor.toplevel, {WheelMove: SocialCalc.EditorProcessMouseWheel, editor: editor});
+
+ if (editor.inputBox) { // this seems to fix an obscure bug with Firefox 2 Mac where Ctrl-V doesn't get fired right
+ if (editor.inputBox.element) {
+ editor.inputBox.element.focus();
+ editor.inputBox.element.blur();
+ }
+ }
+ SocialCalc.KeyboardSetFocus(editor);
+
+ // do status reporting things
+
+ SocialCalc.EditorSheetStatusCallback(null, "startup", null, editor);
+
+ // done
+
+ return editor.toplevel;
+
+ }
+
+//
+// SocialCalc.ResizeTableEditor(editor, width, height)
+//
+// Move things around as appropriate and resize
+//
+
+SocialCalc.ResizeTableEditor = function(editor, width, height) {
+
+ var scc = SocialCalc.Constants;
+
+ editor.width = width;
+ editor.height = height;
+
+ editor.toplevel.style.width = width+"px";
+ editor.toplevel.style.height = height+"px";
+
+ editor.tablewidth = width - scc.defaultTableControlThickness;
+ editor.tableheight = height - scc.defaultTableControlThickness;
+ editor.griddiv.style.width=editor.tablewidth+"px";
+ editor.griddiv.style.height=editor.tableheight+"px";
+
+ editor.verticaltablecontrol.main.style.height = editor.tableheight + "px";
+ editor.horizontaltablecontrol.main.style.width = editor.tablewidth + "px";
+
+ editor.FitToEditTable();
+
+ editor.ScheduleRender();
+
+ return;
+
+ }
+
+//
+// str = SaveEditorSettings(editor)
+//
+// Returns a string representation of the pane settings, etc.
+//
+// The format is:
+//
+// version:1.0
+// rowpane:panenumber:firstnum:lastnum
+// colpane:panenumber:firstnum:lastnum
+// ecell:coord -- if set
+// range:anchorcoord:top:bottom:left:right -- if set
+//
+// You can add additional values to be saved by using editor.SettingsCallbacks:
+//
+// editor.SettingsCallbacks["item-name"] = {save: savefunction, load: loadfunction}
+//
+// where savefunction(editor, "item-name") returns a string with the new lines to be added to the saved settings
+// which include the trailing newlines, and loadfunction(editor, "item-name", line, flags) is given the line to process
+// without the trailing newlines.
+//
+
+SocialCalc.SaveEditorSettings = function(editor) {
+
+ var i, setting;
+ var context = editor.context;
+ var range = editor.range;
+ var result = "";
+
+ result += "version:1.0\n";
+
+ for (i=0; i<context.rowpanes.length; i++) {
+ result += "rowpane:"+i+":"+context.rowpanes[i].first+":"+context.rowpanes[i].last+"\n";
+ }
+ for (i=0; i<context.colpanes.length; i++) {
+ result += "colpane:"+i+":"+context.colpanes[i].first+":"+context.colpanes[i].last+"\n";
+ }
+
+ if (editor.ecell) {
+ result += "ecell:"+editor.ecell.coord+"\n";
+ }
+
+ if (range.hasrange) {
+ result += "range:"+range.anchorcoord+":"+range.top+":"+range.bottom+":"+range.left+":"+range.right+"\n";
+ }
+
+ for (setting in editor.SettingsCallbacks) {
+ result += editor.SettingsCallbacks[setting].save(editor, setting);
+ }
+
+ return result;
+
+ }
+
+//
+// LoadEditorSettings(editor, str, flags)
+//
+// Sets the editor settings based on str. See SocialCalc.SaveEditorSettings for more details.
+// Unrecognized lines are ignored.
+//
+
+SocialCalc.LoadEditorSettings = function(editor, str, flags) {
+
+ var lines=str.split(/\r\n|\n/);
+ var parts=[];
+ var line, i, cr, row, col, coord, setting;
+ var context = editor.context;
+ var highlights, range;
+
+ context.rowpanes = [{first: 1, last: 1}]; // reset to start
+ context.colpanes = [{first: 1, last: 1}];
+ editor.ecell = null;
+ editor.range = {hasrange: false};
+ editor.range2 = {hasrange: false};
+ range = editor.range;
+ context.highlights = {};
+ highlights = context.highlights;
+
+ for (i=0; i<lines.length; i++) {
+ line=lines[i];
+ parts = line.split(":");
+ setting = parts[0];
+ switch (setting) {
+ case "version":
+ break;
+
+ case "rowpane":
+ context.rowpanes[parts[1]-0] = {first: parts[2]-0, last: parts[3]-0};
+ break;
+
+ case "colpane":
+ context.colpanes[parts[1]-0] = {first: parts[2]-0, last: parts[3]-0};
+ break;
+
+ case "ecell":
+ editor.ecell = SocialCalc.coordToCr(parts[1]);
+ editor.ecell.coord = parts[1];
+ highlights[parts[1]] = "cursor";
+ break;
+
+ case "range":
+ range.hasrange = true;
+ range.anchorcoord = parts[1];
+ cr = SocialCalc.coordToCr(range.anchorcoord);
+ range.anchorrow = cr.row;
+ range.anchorcol = cr.col;
+ range.top = parts[2]-0;
+ range.bottom = parts[3]-0;
+ range.left = parts[4]-0;
+ range.right = parts[5]-0;
+ for (row=range.top; row<=range.bottom; row++) {
+ for (col=range.left; col<=range.right; col++) {
+ coord = SocialCalc.crToCoord(col, row);
+ if (highlights[coord]!="cursor") {
+ highlights[coord] = "range";
+ }
+ }
+ }
+ break;
+
+ default:
+ if (editor.SettingsCallbacks[setting]) {
+ editor.SettingsCallbacks[setting].load(editor, setting, line, flags);
+ }
+ break;
+ }
+ }
+
+ return;
+
+ }
+
+//
+// EditorRenderSheet(editor)
+//
+// Renders the sheet and updates editor.fullgrid.
+// Sets event handlers.
+//
+
+SocialCalc.EditorRenderSheet = function(editor) {
+
+ editor.EditorMouseUnregister();
+
+ editor.fullgrid = editor.context.RenderSheet(editor.fullgrid);
+
+ if (editor.ecell) editor.SetECellHeaders("selected");
+
+ SocialCalc.AssignID(editor, editor.fullgrid, "fullgrid"); // give it an id
+
+ editor.EditorMouseRegister();
+
+ }
+
+//
+// EditorScheduleSheetCommands(editor, cmdstr, ignorebusy)
+//
+
+SocialCalc.EditorScheduleSheetCommands = function(editor, cmdstr, ignorebusy) {
+
+ if (editor.state!="start" && !ignorebusy) { // ignore commands if editing a cell
+ return;
+ }
+
+ if (editor.busy && !ignorebusy) { // hold off on commands if doing one
+ editor.deferredCommands.push(cmdstr);
+ return;
+ }
+
+ switch (cmdstr) {
+ case "recalc":
+ case "redisplay":
+ editor.context.sheetobj.ScheduleSheetCommands(cmdstr, false);
+ break;
+
+ case "undo":
+ editor.SheetUndo();
+ break;
+
+ case "redo":
+ editor.SheetRedo();
+ break;
+
+ default:
+ editor.context.sheetobj.ScheduleSheetCommands(cmdstr, true);
+ break;
+ }
+ }
+
+
+//
+// EditorSheetStatusCallback(recalcdata, status, arg, editor)
+//
+// Called during recalc, executing commands, etc.
+//
+
+SocialCalc.EditorSheetStatusCallback = function(recalcdata, status, arg, editor) {
+
+ var f, cell;
+ var sheetobj = editor.context.sheetobj;
+
+ var signalstatus = function(s) {
+ for (f in editor.StatusCallback) {
+ if (editor.StatusCallback[f].func) {
+ editor.StatusCallback[f].func(editor, s, arg, editor.StatusCallback[f].params);
+ }
+ }
+ }
+
+ switch (status) {
+
+ case "startup":
+ break;
+
+ case "cmdstart":
+ editor.busy = true;
+ sheetobj.celldisplayneeded = "";
+ break;
+
+ case "cmdend":
+ signalstatus(status);
+
+ if (sheetobj.changedrendervalues) {
+ editor.context.PrecomputeSheetFontsAndLayouts();
+ editor.context.CalculateCellSkipData();
+ sheetobj.changedrendervalues = false;
+ }
+
+ if (sheetobj.celldisplayneeded && !sheetobj.renderneeded) {
+ cr = SocialCalc.coordToCr(sheetobj.celldisplayneeded);
+ cell = SocialCalc.GetEditorCellElement(editor, cr.row, cr.col);
+ editor.ReplaceCell(cell, cr.row, cr.col);
+ }
+
+ if (editor.deferredCommands.length) {
+ editor.EditorScheduleSheetCommands(editor.deferredCommands.shift(), true);
+ return;
+ }
+
+ if (sheetobj.attribs.needsrecalc &&
+ (sheetobj.attribs.recalc!="off" || sheetobj.recalconce)
+ && editor.recalcFunction) {
+ editor.FitToEditTable();
+ sheetobj.renderneeded = false; // recalc will force a render
+ if (sheetobj.recalconce) delete sheetobj.recalconce; // only do once
+ editor.recalcFunction(editor);
+ }
+ else {
+ if (sheetobj.renderneeded) {
+ editor.FitToEditTable();
+ sheetobj.renderneeded = false;
+ editor.ScheduleRender();
+ }
+ else {
+ editor.SchedulePositionCalculations(); // just in case command changed positions
+// editor.busy = false;
+// signalstatus("cmdendnorender");
+ }
+ }
+ return;
+
+ case "calcstart":
+ editor.busy = true;
+ break;
+
+ case "calccheckdone":
+ case "calcorder":
+ case "calcstep":
+ case "calcloading":
+ case "calcserverfunc":
+ break;
+
+ case "calcfinished":
+ signalstatus(status);
+ editor.ScheduleRender();
+ return;
+
+ case "schedrender":
+ editor.busy = true; // in case got here without cmd or recalc
+ break;
+
+ case "renderdone":
+ break;
+
+ case "schedposcalc":
+ editor.busy = true; // in case got here without cmd or recalc
+ break;
+
+ case "doneposcalc":
+ if (editor.deferredCommands.length) {
+ signalstatus(status);
+ editor.EditorScheduleSheetCommands(editor.deferredCommands.shift(), true);
+ }
+ else {
+ editor.busy = false;
+ signalstatus(status);
+ if (editor.state=="start") editor.DisplayCellContents(); // make sure up to date
+ }
+ return;
+
+ default:
+addmsg("Unknown status: "+status);
+ break;
+
+ }
+
+ signalstatus(status);
+
+ return;
+
+ }
+
+// Timer-driven steps for use with SocialCalc.EditorSheetStatusCallback
+
+SocialCalc.EditorStepInfo = {
+// status: "", // saved value to pass to callback
+ editor: null // for callback
+// arg: null, // for callback
+// timerobj: null
+ };
+
+/*
+SocialCalc.EditorStepSet = function(editor, status, arg) {
+ var esi = SocialCalc.EditorStepInfo;
+addmsg("step: "+status);
+ if (esi.timerobj) {
+alert("Already waiting. Old/new: "+esi.status+"/"+status);
+ }
+ esi.editor = editor;
+ esi.status = status;
+ esi.timerobj = window.setTimeout(SocialCalc.EditorStepDone, 1);
+ }
+
+SocialCalc.EditorStepDone = function() {
+ var esi = SocialCalc.EditorStepInfo;
+ esi.timerobj = null;
+ SocialCalc.EditorSheetStatusCallback(null, esi.status, null, esi.editor);
+ }
+*/
+
+//
+// str = SocialCalc.EditorGetStatuslineString(editor, status, arg, params)
+//
+// Assumes params is an object where it can use "calculating" and "command"
+// to keep track of state.
+// Returns string for status line.
+//
+
+SocialCalc.EditorGetStatuslineString = function(editor, status, arg, params) {
+
+ var scc = SocialCalc.Constants;
+
+ var sstr, progress, coord, circ, r, c, cell, sum, ele;
+
+ progress = "";
+
+ switch (status) {
+ case "moveecell":
+ case "rangechange":
+ case "startup":
+ break;
+ case "cmdstart":
+ params.command = true;
+ document.body.style.cursor = "progress";
+ editor.griddiv.style.cursor = "progress";
+ progress = scc.s_statusline_executing;
+ break;
+ case "cmdend":
+ params.command = false;
+ break;
+ case "schedrender":
+ progress = scc.s_statusline_displaying;
+ break;
+ case "renderdone":
+ progress = " ";
+ break;
+ case "schedposcalc":
+ progress = scc.s_statusline_displaying;
+ break;
+ case "cmdendnorender":
+ case "doneposcalc":
+ document.body.style.cursor = "default";
+ editor.griddiv.style.cursor = "default";
+ break;
+ case "calcorder":
+ progress = scc.s_statusline_ordering+Math.floor(100*arg.count/(arg.total||1))+"%";
+ break;
+ case "calcstep":
+ progress = scc.s_statusline_calculating+Math.floor(100*arg.count/(arg.total||1))+"%";
+ break;
+ case "calcloading":
+ progress = scc.s_statusline_calculatingls+": "+arg.sheetname;
+ break;
+ case "calcserverfunc":
+ progress = scc.s_statusline_calculating+Math.floor(100*arg.count/(arg.total||1))+"%, "+scc.s_statusline_doingserverfunc+arg.funcname+scc.s_statusline_incell+arg.coord;
+ break;
+ case "calcstart":
+ params.calculating = true;
+ document.body.style.cursor = "progress";
+ editor.griddiv.style.cursor = "progress"; // griddiv has an explicit cursor style
+ progress = scc.s_statusline_calcstart;
+ break;
+ case "calccheckdone":
+ break;
+ case "calcfinished":
+ params.calculating = false;
+ break;
+ default:
+ progress = status;
+ break;
+ }
+
+ if (!progress && params.calculating) {
+ progress = scc.s_statusline_calculating;
+ }
+
+ // if there is a range, calculate sum (not during busy times)
+ if (!params.calculating && !params.command && !progress && editor.range.hasrange
+ && (editor.range.left!=editor.range.right || editor.range.top!=editor.range.bottom)) {
+ sum = 0;
+ for (r=editor.range.top; r <= editor.range.bottom; r++) {
+ for (c=editor.range.left; c <= editor.range.right; c++) {
+ cell = editor.context.sheetobj.cells[SocialCalc.crToCoord(c, r)];
+ if (!cell) continue;
+ if (cell.valuetype && cell.valuetype.charAt(0)=="n") {
+ sum += cell.datavalue-0;
+ }
+ }
+ }
+
+ sum = SocialCalc.FormatNumber.formatNumberWithFormat(sum, "[,]General", "");
+
+ coord = SocialCalc.crToCoord(editor.range.left, editor.range.top) + ":" +
+ SocialCalc.crToCoord(editor.range.right, editor.range.bottom);
+ progress = coord + " (" + (editor.range.right-editor.range.left+1) + "x" + (editor.range.bottom-editor.range.top+1) +
+ ") "+scc.s_statusline_sum+"=" + sum + " " + progress;
+ }
+ sstr = editor.ecell.coord+" &nbsp; "+progress;
+
+ if (!params.calculating && editor.context.sheetobj.attribs.needsrecalc=="yes") {
+ sstr += ' &nbsp; '+scc.s_statusline_recalcneeded;
+ }
+
+ circ = editor.context.sheetobj.attribs.circularreferencecell;
+ if (circ) {
+ circ = circ.replace(/\|/, " referenced by ");
+ sstr += ' &nbsp; '+scc.s_statusline_circref + circ + '</span>';
+ }
+
+ return sstr;
+
+ }
+
+
+//
+// Mouse stuff
+//
+
+SocialCalc.EditorMouseInfo = {
+
+ // The registeredElements array is used to identify editor grid in which the mouse is doing things.
+
+ // One item for each active editor, each an object with:
+ // .element, .editor
+
+ registeredElements: [],
+
+ editor: null, // editor being processed (between mousedown and mouseup)
+ element: null, // element being processed
+
+ ignore: false, // if true, mousedowns are ignored
+
+ mousedowncoord: "", // coord where mouse went down for drag range
+ mouselastcoord: "", // coord where mouse last was during drag
+ mouseresizecol: "", // col being resized
+ mouseresizeclientx: null, // where resize started
+ mouseresizedisplay: null // element tracking new size
+ }
+
+//
+// EditorMouseRegister(editor)
+//
+
+SocialCalc.EditorMouseRegister = function(editor) {
+
+ var mouseinfo = SocialCalc.EditorMouseInfo;
+ var element = editor.fullgrid;
+ var i;
+
+ for (i=0; i<mouseinfo.registeredElements.length; i++) {
+ if (mouseinfo.registeredElements[i].editor == editor) {
+ if (mouseinfo.registeredElements[i].element == element) {
+ return; // already set - don't do it again
+ }
+ break;
+ }
+ }
+
+ if (i<mouseinfo.registeredElements.length) {
+ mouseinfo.registeredElements[i].element = element;
+ }
+ else {
+ mouseinfo.registeredElements.push({element: element, editor: editor});
+ }
+
+ if (element.addEventListener) { // DOM Level 2 -- Firefox, et al
+ element.addEventListener("mousedown", SocialCalc.ProcessEditorMouseDown, false);
+ element.addEventListener("dblclick", SocialCalc.ProcessEditorDblClick, false);
+ }
+ else if (element.attachEvent) { // IE 5+
+ element.attachEvent("onmousedown", SocialCalc.ProcessEditorMouseDown);
+ element.attachEvent("ondblclick", SocialCalc.ProcessEditorDblClick);
+ }
+ else { // don't handle this
+ throw "Browser not supported";
+ }
+
+ return;
+
+ }
+
+//
+// EditorMouseUnregister(editor)
+//
+
+SocialCalc.EditorMouseUnregister = function(editor) {
+
+ var mouseinfo = SocialCalc.EditorMouseInfo;
+ var element = editor.fullgrid;
+ var i, oldelement;
+
+ for (i=0; i<mouseinfo.registeredElements.length; i++) {
+ if (mouseinfo.registeredElements[i].editor == editor) {
+ break;
+ }
+ }
+
+ if (i<mouseinfo.registeredElements.length) {
+ oldelement = mouseinfo.registeredElements[i].element; // remove old handlers
+ if (oldelement.removeEventListener) { // DOM Level 2
+ oldelement.removeEventListener("mousedown", SocialCalc.ProcessEditorMouseDown, false);
+ oldelement.removeEventListener("dblclick", SocialCalc.ProcessEditorDblClick, false);
+ }
+ else if (oldelement.detachEvent) { // IE
+ oldelement.detachEvent("onmousedown", SocialCalc.ProcessEditorMouseDown);
+ oldelement.detachEvent("ondblclick", SocialCalc.ProcessEditorDblClick);
+ }
+ mouseinfo.registeredElements.splice(i, 1);
+ }
+
+ return;
+
+ }
+
+SocialCalc.ProcessEditorMouseDown = function(e) {
+
+ var editor, result, coord, textarea, wval, range;
+
+ var event = e || window.event;
+
+ var viewport = SocialCalc.GetViewportInfo();
+ var clientX = event.clientX + viewport.horizontalScroll;
+ var clientY = event.clientY + viewport.verticalScroll;
+
+ var mouseinfo = SocialCalc.EditorMouseInfo;
+ var ele = event.target || event.srcElement; // source object is often within what we want
+ var mobj;
+
+ if (mouseinfo.ignore) return; // ignore this
+
+ for (mobj=null; !mobj && ele; ele=ele.parentNode) { // go up tree looking for one of our elements
+ mobj = SocialCalc.LookupElement(ele, mouseinfo.registeredElements);
+ }
+ if (!mobj) {
+ mouseinfo.editor = null;
+ return; // not one of our elements
+ }
+
+ editor = mobj.editor;
+ mouseinfo.element = ele;
+ range = editor.range;
+ result = SocialCalc.GridMousePosition(editor, clientX, clientY);
+
+ if (!result || result.rowheader) return; // not on a cell or col header
+ mouseinfo.editor = editor; // remember for later
+
+ if (result.colheader && result.coltoresize) { // col header - do drag resize
+ SocialCalc.ProcessEditorColsizeMouseDown(e, ele, result);
+ return;
+ }
+
+ if (!result.coord) return; // not us
+
+ if (!range.hasrange) {
+ if (e.shiftKey)
+ editor.RangeAnchor();
+ }
+
+ coord = editor.MoveECell(result.coord);
+
+ if (range.hasrange) {
+ if (e.shiftKey)
+ editor.RangeExtend();
+ else
+ editor.RangeRemove();
+ }
+
+ mouseinfo.mousedowncoord = coord; // remember if starting drag range select
+ mouseinfo.mouselastcoord = coord;
+
+ editor.EditorMouseRange(coord);
+
+ SocialCalc.KeyboardSetFocus(editor);
+ if (editor.state!="start" && editor.inputBox) editor.inputBox.element.focus();
+
+ // Event code from JavaScript, Flanagan, 5th Edition, pg. 422
+ if (document.addEventListener) { // DOM Level 2 -- Firefox, et al
+ document.addEventListener("mousemove", SocialCalc.ProcessEditorMouseMove, true); // capture everywhere
+ document.addEventListener("mouseup", SocialCalc.ProcessEditorMouseUp, true); // capture everywhere
+ }
+ else if (ele.attachEvent) { // IE 5+
+ ele.setCapture();
+ ele.attachEvent("onmousemove", SocialCalc.ProcessEditorMouseMove);
+ ele.attachEvent("onmouseup", SocialCalc.ProcessEditorMouseUp);
+ ele.attachEvent("onlosecapture", SocialCalc.ProcessEditorMouseUp);
+ }
+ if (event.stopPropagation) event.stopPropagation(); // DOM Level 2
+ else event.cancelBubble = true; // IE 5+
+ if (event.preventDefault) event.preventDefault(); // DOM Level 2
+ else event.returnValue = false; // IE 5+
+
+ return;
+
+ }
+
+SocialCalc.EditorMouseRange = function(editor, coord) {
+
+ var inputtext, wval;
+ var range = editor.range;
+
+ switch (editor.state) { // editing a cell - shouldn't get here if no inputBox
+ case "input":
+ inputtext = editor.inputBox.GetText();
+ wval = editor.workingvalues;
+ if (("(+-*/,:!&<>=^".indexOf(inputtext.slice(-1))>=0 && inputtext.slice(0,1)=="=") ||
+ (inputtext == "=")) {
+ wval.partialexpr = inputtext;
+ }
+
+ if (wval.partialexpr) { // if in pointing operation
+ if (coord) {
+ if (range.hasrange) {
+ editor.inputBox.SetText(wval.partialexpr + SocialCalc.crToCoord(range.left, range.top) + ":" +
+ SocialCalc.crToCoord(range.right, range.bottom));
+ }
+ else {
+ editor.inputBox.SetText(wval.partialexpr + coord);
+ }
+ }
+ }
+ else { // not in point -- done editing
+ editor.inputBox.Blur();
+ editor.inputBox.ShowInputBox(false);
+ editor.state = "start";
+ editor.EditorSaveEdit();
+ editor.inputBox.DisplayCellContents(null);
+ }
+ break;
+
+ case "inputboxdirect":
+ editor.inputBox.Blur();
+ editor.inputBox.ShowInputBox(false);
+ editor.state = "start";
+ editor.EditorSaveEdit();
+ editor.inputBox.DisplayCellContents(null);
+ break;
+ }
+ }
+
+SocialCalc.ProcessEditorMouseMove = function(e) {
+
+ var editor, element, result, coord, now, textarea, sheetobj, cellobj, wval;
+
+ var event = e || window.event;
+
+ var viewport = SocialCalc.GetViewportInfo();
+ var clientX = event.clientX + viewport.horizontalScroll;
+ var clientY = event.clientY + viewport.verticalScroll;
+
+ var mouseinfo = SocialCalc.EditorMouseInfo;
+ editor = mouseinfo.editor;
+ if (!editor) return; // not us, ignore
+ element = mouseinfo.element;
+
+ result = SocialCalc.GridMousePosition(editor, clientX, clientY); // get cell with move
+ if (!result || !result.coord) return;
+
+ if (result.coord!=mouseinfo.mouselastcoord) {
+ if (!e.shiftKey && !editor.range.hasrange) {
+ editor.RangeAnchor(mouseinfo.mousedowncoord);
+ }
+ editor.MoveECell(result.coord);
+ editor.RangeExtend();
+ }
+ mouseinfo.mouselastcoord = result.coord;
+
+ editor.EditorMouseRange(result.coord);
+
+ if (event.stopPropagation) event.stopPropagation(); // DOM Level 2
+ else event.cancelBubble = true; // IE 5+
+ if (event.preventDefault) event.preventDefault(); // DOM Level 2
+ else event.returnValue = false; // IE 5+
+
+ return;
+
+ }
+
+
+SocialCalc.ProcessEditorMouseUp = function(e) {
+
+ var editor, element, result, coord, now, textarea, sheetobj, cellobj, wval;
+
+ var event = e || window.event;
+
+ var viewport = SocialCalc.GetViewportInfo();
+ var clientX = event.clientX + viewport.horizontalScroll;
+ var clientY = event.clientY + viewport.verticalScroll;
+
+ var mouseinfo = SocialCalc.EditorMouseInfo;
+ editor = mouseinfo.editor;
+ if (!editor) return; // not us, ignore
+ element = mouseinfo.element;
+
+ result = SocialCalc.GridMousePosition(editor, clientX, clientY); // get cell with up
+
+ if (!result) return;
+
+ if (!result.coord) result.coord = editor.ecell.coord;
+
+ if (editor.range.hasrange) {
+ editor.MoveECell(result.coord);
+ editor.RangeExtend();
+ }
+ else if (result.coord && result.coord!=mouseinfo.mousedowncoord) {
+ editor.RangeAnchor(mouseinfo.mousedowncoord);
+ editor.MoveECell(result.coord);
+ editor.RangeExtend();
+ }
+
+ editor.EditorMouseRange(result.coord);
+
+ if (event.stopPropagation) event.stopPropagation(); // DOM Level 2
+ else event.cancelBubble = true; // IE 5+
+ if (event.preventDefault) event.preventDefault(); // DOM Level 2
+ else event.returnValue = false; // IE 5+
+
+ if (document.removeEventListener) { // DOM Level 2
+ document.removeEventListener("mousemove", SocialCalc.ProcessEditorMouseMove, true);
+ document.removeEventListener("mouseup", SocialCalc.ProcessEditorMouseUp, true);
+ }
+ else if (element.detachEvent) { // IE
+ element.detachEvent("onlosecapture", SocialCalc.ProcessEditorMouseUp);
+ element.detachEvent("onmouseup", SocialCalc.ProcessEditorMouseUp);
+ element.detachEvent("onmousemove", SocialCalc.ProcessEditorMouseMove);
+ element.releaseCapture();
+ }
+
+ mouseinfo.editor = null;
+
+ return false;
+
+ }
+
+
+SocialCalc.ProcessEditorColsizeMouseDown = function(e, ele, result) {
+
+ var event = e || window.event;
+ var mouseinfo = SocialCalc.EditorMouseInfo;
+ var editor = mouseinfo.editor;
+ var viewport = SocialCalc.GetViewportInfo();
+ var clientX = event.clientX + viewport.horizontalScroll;
+
+ mouseinfo.mouseresizecolnum = result.coltoresize; // remember col being resized
+ mouseinfo.mouseresizecol = SocialCalc.rcColname(result.coltoresize);
+ mouseinfo.mousedownclientx = clientX;
+
+ var sizedisplay = document.createElement("div");
+ mouseinfo.mouseresizedisplay = sizedisplay;
+ sizedisplay.style.width = "auto";
+ sizedisplay.style.position = "absolute";
+ sizedisplay.style.zIndex = 100;
+ sizedisplay.style.top = (editor.headposition.top+0)+"px";
+ sizedisplay.style.left = editor.colpositions[result.coltoresize]+"px";
+ sizedisplay.innerHTML = '<table cellpadding="0" cellspacing="0"><tr><td style="height:100px;'+
+ 'border:1px dashed black;background-color:white;width:' +
+ (editor.context.colwidth[mouseinfo.mouseresizecolnum]-2) + 'px;">&nbsp;</td>'+
+ '<td><div style="font-size:small;color:white;background-color:gray;padding:4px;">'+
+ editor.context.colwidth[mouseinfo.mouseresizecolnum] + '</div></td></tr></table>';
+ SocialCalc.setStyles(sizedisplay.firstChild.lastChild.firstChild.childNodes[0], "filter:alpha(opacity=85);opacity:.85;"); // so no warning msg with Firefox about filter
+
+ editor.toplevel.appendChild(sizedisplay);
+
+ // Event code from JavaScript, Flanagan, 5th Edition, pg. 422
+ if (document.addEventListener) { // DOM Level 2 -- Firefox, et al
+ document.addEventListener("mousemove", SocialCalc.ProcessEditorColsizeMouseMove, true); // capture everywhere
+ document.addEventListener("mouseup", SocialCalc.ProcessEditorColsizeMouseUp, true); // capture everywhere
+ }
+ else if (editor.toplevel.attachEvent) { // IE 5+
+ editor.toplevel.setCapture();
+ editor.toplevel.attachEvent("onmousemove", SocialCalc.ProcessEditorColsizeMouseMove);
+ editor.toplevel.attachEvent("onmouseup", SocialCalc.ProcessEditorColsizeMouseUp);
+ editor.toplevel.attachEvent("onlosecapture", SocialCalc.ProcessEditorColsizeMouseUp);
+ }
+ if (event.stopPropagation) event.stopPropagation(); // DOM Level 2
+ else event.cancelBubble = true; // IE 5+
+ if (event.preventDefault) event.preventDefault(); // DOM Level 2
+ else event.returnValue = false; // IE 5+
+
+ return;
+ }
+
+
+SocialCalc.ProcessEditorColsizeMouseMove = function(e) {
+
+ var event = e || window.event;
+ var mouseinfo = SocialCalc.EditorMouseInfo;
+ var editor = mouseinfo.editor;
+ if (!editor) return; // not us, ignore
+ var viewport = SocialCalc.GetViewportInfo();
+ var clientX = event.clientX + viewport.horizontalScroll;
+
+ var newsize = (editor.context.colwidth[mouseinfo.mouseresizecolnum]-0) + (clientX - mouseinfo.mousedownclientx);
+ if (newsize < SocialCalc.Constants.defaultMinimumColWidth) newsize = SocialCalc.Constants.defaultMinimumColWidth;
+
+ var sizedisplay = mouseinfo.mouseresizedisplay;
+// sizedisplay.firstChild.lastChild.firstChild.childNodes[1].firstChild.innerHTML = newsize+"";
+// sizedisplay.firstChild.lastChild.firstChild.childNodes[0].firstChild.style.width = (newsize-2)+"px";
+ sizedisplay.innerHTML = '<table cellpadding="0" cellspacing="0"><tr><td style="height:100px;'+
+ 'border:1px dashed black;background-color:white;width:' + (newsize-2) + 'px;">&nbsp;</td>'+
+ '<td><div style="font-size:small;color:white;background-color:gray;padding:4px;">'+
+ newsize + '</div></td></tr></table>';
+ SocialCalc.setStyles(sizedisplay.firstChild.lastChild.firstChild.childNodes[0], "filter:alpha(opacity=85);opacity:.85;"); // so no warning msg with Firefox about filter
+
+ if (event.stopPropagation) event.stopPropagation(); // DOM Level 2
+ else event.cancelBubble = true; // IE 5+
+ if (event.preventDefault) event.preventDefault(); // DOM Level 2
+ else event.returnValue = false; // IE 5+
+
+ return;
+
+ }
+
+
+SocialCalc.ProcessEditorColsizeMouseUp = function(e) {
+
+ var event = e || window.event;
+ var mouseinfo = SocialCalc.EditorMouseInfo;
+ var editor = mouseinfo.editor;
+ if (!editor) return; // not us, ignore
+ element = mouseinfo.element;
+ var viewport = SocialCalc.GetViewportInfo();
+ var clientX = event.clientX + viewport.horizontalScroll;
+
+ if (event.stopPropagation) event.stopPropagation(); // DOM Level 2
+ else event.cancelBubble = true; // IE 5+
+ if (event.preventDefault) event.preventDefault(); // DOM Level 2
+ else event.returnValue = false; // IE 5+
+
+ if (document.removeEventListener) { // DOM Level 2
+ document.removeEventListener("mousemove", SocialCalc.ProcessEditorColsizeMouseMove, true);
+ document.removeEventListener("mouseup", SocialCalc.ProcessEditorColsizeMouseUp, true);
+ }
+ else if (editor.toplevel.detachEvent) { // IE
+ editor.toplevel.detachEvent("onlosecapture", SocialCalc.ProcessEditorColsizeMouseUp);
+ editor.toplevel.detachEvent("onmouseup", SocialCalc.ProcessEditorColsizeMouseUp);
+ editor.toplevel.detachEvent("onmousemove", SocialCalc.ProcessEditorColsizeMouseMove);
+ editor.toplevel.releaseCapture();
+ }
+
+ var newsize = (editor.context.colwidth[mouseinfo.mouseresizecolnum]-0) + (clientX - mouseinfo.mousedownclientx);
+ if (newsize < SocialCalc.Constants.defaultMinimumColWidth) newsize = SocialCalc.Constants.defaultMinimumColWidth;
+
+ editor.EditorScheduleSheetCommands("set "+mouseinfo.mouseresizecol+" width "+newsize);
+
+ if (editor.timeout) window.clearTimeout(editor.timeout);
+ editor.timeout = window.setTimeout(SocialCalc.FinishColsize, 1); // wait - Firefox 2 has a bug otherwise with next mousedown
+
+ return false;
+
+ }
+
+
+SocialCalc.FinishColsize = function() {
+
+ var mouseinfo = SocialCalc.EditorMouseInfo;
+ var editor = mouseinfo.editor;
+ if (!editor) return;
+
+ editor.toplevel.removeChild(mouseinfo.mouseresizedisplay);
+ mouseinfo.mouseresizedisplay = null;
+
+// editor.FitToEditTable();
+// editor.EditorRenderSheet();
+// editor.SchedulePositionCalculations();
+
+ mouseinfo.editor = null;
+
+ return;
+
+ }
+
+
+SocialCalc.ProcessEditorDblClick = function(e) {
+
+ var editor, result, coord, textarea, wval, range;
+
+ var event = e || window.event;
+
+ var viewport = SocialCalc.GetViewportInfo();
+ var clientX = event.clientX + viewport.horizontalScroll;
+ var clientY = event.clientY + viewport.verticalScroll;
+
+ var mouseinfo = SocialCalc.EditorMouseInfo;
+ var ele = event.target || event.srcElement; // source object is often within what we want
+ var mobj;
+
+ if (mouseinfo.ignore) return; // ignore this
+
+ for (mobj=null; !mobj && ele; ele=ele.parentNode) { // go up tree looking for one of our elements
+ mobj = SocialCalc.LookupElement(ele, mouseinfo.registeredElements);
+ }
+ if (!mobj) {
+ mouseinfo.editor = null;
+ return; // not one of our elements
+ }
+
+ editor = mobj.editor;
+
+ result = SocialCalc.GridMousePosition(editor, clientX, clientY);
+ if (!result || !result.coord) return; // not within cell area - ignore
+
+ mouseinfo.editor = editor; // remember for later
+ mouseinfo.element = ele;
+ range = editor.range;
+
+ sheetobj = editor.context.sheetobj;
+
+ switch (editor.state) {
+ case "start":
+ SocialCalc.EditorOpenCellEdit(editor);
+ break;
+
+ case "input":
+ break;
+
+ default:
+ break;
+ }
+
+ if (event.stopPropagation) event.stopPropagation(); // DOM Level 2
+ else event.cancelBubble = true; // IE 5+
+ if (event.preventDefault) event.preventDefault(); // DOM Level 2
+ else event.returnValue = false; // IE 5+
+
+ return;
+
+ }
+
+
+SocialCalc.EditorOpenCellEdit = function(editor) {
+
+ var wval;
+
+ if (!editor.ecell) return true; // no ecell
+ if (!editor.inputBox) return true; // no input box, so no editing
+ if (editor.inputBox.element.disabled) return true; // multi-line: ignore
+ editor.inputBox.ShowInputBox(true);
+ editor.inputBox.Focus();
+ editor.state = "inputboxdirect";
+ editor.inputBox.SetText("");
+ editor.inputBox.DisplayCellContents();
+ editor.inputBox.Select("end");
+ wval = editor.workingvalues;
+ wval.partialexpr = "";
+ wval.ecoord = editor.ecell.coord;
+ wval.erow = editor.ecell.row;
+ wval.ecol = editor.ecell.col;
+
+ return;
+
+ }
+
+
+SocialCalc.EditorProcessKey = function(editor, ch, e) {
+
+ var result, cell, cellobj, valueinfo, fch, coord, inputtext, f;
+
+ var sheetobj = editor.context.sheetobj;
+ var wval = editor.workingvalues;
+ var range = editor.range;
+
+ if (typeof ch != "string") ch = "";
+
+ switch (editor.state) {
+ case "start":
+ if (e.shiftKey && ch.substr(0,2)=="[a") {
+ ch = ch + "shifted";
+ }
+ if (ch=="[enter]") ch = "[adown]";
+ if (ch=="[tab]") ch = e.shiftKey ? "[aleft]" : "[aright]";
+ if (ch.substr(0,2)=="[a" || ch.substr(0,3)=="[pg" || ch=="[home]") {
+ result = editor.MoveECellWithKey(ch);
+ return !result;
+ }
+ if (ch=="[del]" || ch=="[backspace]") {
+ editor.EditorApplySetCommandsToRange("empty", "");
+ break;
+ }
+ if (ch=="[esc]") {
+ if (range.hasrange) {
+ editor.RangeRemove();
+ editor.MoveECell(range.anchorcoord);
+ for (f in editor.StatusCallback) {
+ editor.StatusCallback[f].func(editor, "specialkey", ch, editor.StatusCallback[f].params);
+ }
+ }
+ return false;
+ }
+
+ if (ch=="[f2]") {
+ SocialCalc.EditorOpenCellEdit(editor);
+ return false;
+ }
+
+ if ((ch.length>1 && ch.substr(0,1)=="[") || ch.length==0) { // some control key
+ if (editor.ctrlkeyFunction && ch.length>0) {
+ return editor.ctrlkeyFunction(editor, ch);
+ }
+ else {
+ return true;
+ }
+ }
+ if (!editor.ecell) return true; // no ecell
+ if (!editor.inputBox) return true; // no inputBox so no editing
+ editor.inputBox.element.disabled = false; // make sure editable
+ editor.state = "input";
+ editor.inputBox.ShowInputBox(true);
+ editor.inputBox.Focus();
+ editor.inputBox.SetText(ch);
+ editor.inputBox.Select("end");
+ wval.partialexpr = "";
+ wval.ecoord = editor.ecell.coord;
+ wval.erow = editor.ecell.row;
+ wval.ecol = editor.ecell.col;
+ editor.RangeRemove();
+ break;
+
+ case "input":
+ inputtext = editor.inputBox.GetText(); // should not get here if no inputBox
+ if (editor.inputBox.skipOne) return false; // ignore a key already handled
+ if (ch=="[esc]" || ch=="[enter]" || ch=="[tab]" || (ch && ch.substr(0,2)=="[a")) {
+ if (("(+-*/,:!&<>=^".indexOf(inputtext.slice(-1))>=0 && inputtext.slice(0,1)=="=") ||
+ (inputtext == "=")) {
+ wval.partialexpr = inputtext;
+ }
+ if (wval.partialexpr) { // if in pointing operation
+ if (e.shiftKey && ch.substr(0,2)=="[a") {
+ ch = ch + "shifted";
+ }
+ coord = editor.MoveECellWithKey(ch);
+ if (coord) {
+ if (range.hasrange) {
+ editor.inputBox.SetText(wval.partialexpr + SocialCalc.crToCoord(range.left, range.top) + ":" +
+ SocialCalc.crToCoord(range.right, range.bottom));
+ }
+ else {
+ editor.inputBox.SetText(wval.partialexpr + coord);
+ }
+ return false;
+ }
+ }
+ editor.inputBox.Blur();
+ editor.inputBox.ShowInputBox(false);
+ editor.state = "start";
+ if (ch != "[esc]") {
+ editor.EditorSaveEdit();
+ if (editor.ecell.coord != wval.ecoord) {
+ editor.MoveECell(wval.ecoord);
+ }
+ if (ch=="[enter]") ch = "[adown]";
+ if (ch=="[tab]") ch = e.shiftKey ? "[aleft]" : "[aright]";
+ if (ch.substr(0,2)=="[a") {
+ editor.MoveECellWithKey(ch);
+ }
+ }
+ else {
+ editor.inputBox.DisplayCellContents();
+ editor.RangeRemove();
+ editor.MoveECell(wval.ecoord);
+ }
+ break;
+ }
+ if (wval.partialexpr && ch=="[backspace]") {
+ editor.inputBox.SetText(wval.partialexpr);
+ wval.partialexpr = "";
+ editor.RangeRemove();
+ editor.MoveECell(wval.ecoord);
+ return false;
+ }
+ if (ch=="[f2]") return false;
+ if (range.hasrange) {
+ editor.RangeRemove();
+ }
+ editor.MoveECell(wval.ecoord);
+ wval.partialexpr = ""; // not pointing
+ return true;
+
+ case "inputboxdirect":
+ inputtext = editor.inputBox.GetText(); // should not get here if no inputBox
+ if (ch=="[esc]" || ch=="[enter]" || ch=="[tab]") {
+ editor.inputBox.Blur();
+ editor.inputBox.ShowInputBox(false);
+ editor.state = "start";
+ if (ch == "[esc]") {
+ editor.inputBox.DisplayCellContents();
+ }
+ else {
+ editor.EditorSaveEdit();
+ if (editor.ecell.coord != wval.ecoord) {
+ editor.MoveECell(wval.ecoord);
+ }
+ if (ch=="[enter]") ch = "[adown]";
+ if (ch=="[tab]") ch = e.shiftKey ? "[aleft]" : "[aright]";
+ if (ch.substr(0,2)=="[a") {
+ editor.MoveECellWithKey(ch);
+ }
+ }
+ break;
+ }
+ if (ch=="[f2]") return false;
+ return true;
+
+ case "skip-and-start":
+ editor.state = "start";
+ return false;
+
+ default:
+ return true;
+ }
+
+ return false;
+
+ }
+
+SocialCalc.EditorAddToInput = function(editor, str, prefix) {
+
+ var wval = editor.workingvalues;
+
+ switch (editor.state) {
+ case "start":
+ editor.state = "input";
+ editor.inputBox.ShowInputBox(true);
+ editor.inputBox.element.disabled = false; // make sure editable and overwrite old
+ editor.inputBox.Focus();
+ editor.inputBox.SetText((prefix||"")+str);
+ editor.inputBox.Select("end");
+ wval.partialexpr = "";
+ wval.ecoord = editor.ecell.coord;
+ wval.erow = editor.ecell.row;
+ wval.ecol = editor.ecell.col;
+ editor.RangeRemove();
+ break;
+
+ case "input":
+ case "inputboxdirect":
+ editor.inputBox.element.focus();
+ if (wval.partialexpr) {
+ editor.inputBox.SetText(wval.partialexpr);
+ wval.partialexpr = "";
+ editor.RangeRemove();
+ editor.MoveECell(wval.ecoord);
+ }
+ editor.inputBox.SetText(editor.inputBox.GetText()+str);
+ break;
+
+ default:
+ break;
+ }
+
+ }
+
+
+SocialCalc.EditorDisplayCellContents = function(editor) {
+
+ if (editor.inputBox) editor.inputBox.DisplayCellContents();
+
+ }
+
+SocialCalc.EditorSaveEdit = function(editor, text) {
+
+ var result, cell, valueinfo, fch, type, value, oldvalue, cmdline;
+
+ var sheetobj = editor.context.sheetobj;
+ var wval = editor.workingvalues;
+
+ type = "text t";
+ value = typeof text == "string" ? text : editor.inputBox.GetText(); // either explicit or from input box
+
+ oldvalue = SocialCalc.GetCellContents(sheetobj, wval.ecoord)+"";
+ if (value == oldvalue) { // no change
+ return;
+ }
+ fch = value.charAt(0);
+ if (fch=="=" && value.indexOf("\n")==-1) {
+ type = "formula";
+ value = value.substring(1);
+ }
+ else if (fch=="'") {
+ type = "text t";
+ value = value.substring(1);
+ }
+ else if (value.length==0) {
+ type = "empty";
+ }
+ else {
+ valueinfo = SocialCalc.DetermineValueType(value)
+ if (valueinfo.type=="n" && value==(valueinfo.value+"")) { // see if don't need "constant"
+ type = "value n";
+ }
+ else if (valueinfo.type.charAt(0)=="t") {
+ type = "text "+valueinfo.type;
+ }
+ else if (valueinfo.type=="") {
+ type = "text t";
+ }
+ else {
+ type = "constant "+valueinfo.type+" "+valueinfo.value;
+ }
+ }
+
+ if (type.charAt(0)=="t") { // text
+ value = SocialCalc.encodeForSave(value); // newlines, :, and \ are escaped
+ }
+
+ cmdline = "set "+wval.ecoord+" "+type+" "+value;
+ editor.EditorScheduleSheetCommands(cmdline);
+
+ return;
+
+ }
+
+//
+// SocialCalc.EditorApplySetCommandsToRange(editor, cmd)
+//
+// Takes ecell or range and does a "set" command with cmd.
+//
+
+SocialCalc.EditorApplySetCommandsToRange = function(editor, cmd) {
+
+ var cell, row, col, line, errortext;
+
+ var sheetobj = editor.context.sheetobj;
+ var ecell = editor.ecell;
+ var range = editor.range;
+
+ if (range.hasrange) {
+ coord = SocialCalc.crToCoord(range.left, range.top)+":"+SocialCalc.crToCoord(range.right, range.bottom);
+ line = "set "+coord+" "+cmd;
+ errortext = editor.EditorScheduleSheetCommands(line);
+ }
+ else {
+ line = "set "+ecell.coord+" "+cmd;
+ errortext = editor.EditorScheduleSheetCommands(line);
+ }
+
+ editor.DisplayCellContents();
+
+ }
+
+SocialCalc.EditorProcessMouseWheel = function(event, delta, mousewheelinfo, wobj) {
+
+ if (wobj.functionobj.editor.busy) return; // ignore if busy
+
+ if (delta > 0) {
+ wobj.functionobj.editor.ScrollRelative(true, -1);
+ }
+ if (delta < 0) {
+ wobj.functionobj.editor.ScrollRelative(true, +1);
+ }
+
+ }
+
+//
+// GridMousePosition(editor, clientX, clientY)
+//
+// Returns an object with row and col numbers and coord (spans handled for coords),
+// and rowheader/colheader true if in header (where coord will be undefined).
+// If in colheader, will return coltoresize if on appropriate place in col header.
+//
+
+SocialCalc.GridMousePosition = function(editor, clientX, clientY) {
+
+ var row, col, colpane;
+ var result = {};
+
+ for (row=1; row<editor.rowpositions.length; row++) {
+ if (!editor.rowheight[row]) continue; // not rendered yet -- may be above or below us
+ if (editor.rowpositions[row]+editor.rowheight[row]>clientY) {
+ break;
+ }
+ }
+ for (col=1; col<editor.colpositions.length; col++) {
+ if (!editor.colwidth[col]) continue;
+ if (editor.colpositions[col]+editor.colwidth[col]>clientX) {
+ break;
+ }
+ }
+
+ result.row = row;
+ result.col = col;
+
+ if (editor.headposition) {
+ if (clientX < editor.headposition.left && clientX >= editor.gridposition.left) {
+ result.rowheader = true;
+ return result;
+ }
+ else if (clientY < editor.headposition.top && clientY > editor.gridposition.top) { // > because of sizing row
+ result.colheader = true;
+ result.coltoresize = col-(editor.colpositions[col]+editor.colwidth[col]/2>clientX?1:0) || 1;
+ for (colpane=0; colpane<editor.context.colpanes.length; colpane++) {
+ if (result.coltoresize >= editor.context.colpanes[colpane].first &&
+ result.coltoresize <= editor.context.colpanes[colpane].last) { // visible column
+ return result;
+ }
+ }
+ delete result.coltoresize;
+ return result;
+ }
+ else if (clientX >= editor.verticaltablecontrol.controlborder ||
+ clientY >= editor.horizontaltablecontrol.controlborder ||
+ clientX < editor.gridposition.left || clientY <= editor.gridposition.top) {
+ return result;
+ }
+ else {
+ result.coord = SocialCalc.crToCoord(result.col, result.row);
+ if (editor.context.cellskip[result.coord]) { // handle skipped cells
+ result.coord = editor.context.cellskip[result.coord];
+ }
+ return result;
+ }
+ }
+
+ return null;
+
+ }
+
+//
+// GetEditorCellElement(editor, row, col)
+//
+// Returns an object with element, the table cell element in the DOM that corresponds to row and column,
+// as well as rowpane and colpane, the panes with the cell.
+// If no such element, then returns null;
+//
+
+SocialCalc.GetEditorCellElement = function(editor, row, col) {
+
+ var rowpane, colpane, c, coord;
+ var rowindex = 0;
+ var colindex = 0;
+
+ for (rowpane=0; rowpane<editor.context.rowpanes.length; rowpane++) {
+ if (row >= editor.context.rowpanes[rowpane].first && row <= editor.context.rowpanes[rowpane].last) {
+ for (colpane=0; colpane<editor.context.colpanes.length; colpane++) {
+ if (col >= editor.context.colpanes[colpane].first && col <= editor.context.colpanes[colpane].last) {
+ rowindex += row - editor.context.rowpanes[rowpane].first + 2;
+ for (c=editor.context.colpanes[colpane].first; c<=col; c++) {
+ coord=editor.context.cellskip[SocialCalc.crToCoord(c,row)];
+ if (!coord || !editor.context.CoordInPane(coord, rowpane, colpane)) // don't count col-spanned cells
+ colindex++;
+ }
+ return {
+ element: editor.griddiv.firstChild.lastChild.childNodes[rowindex].childNodes[colindex],
+ rowpane: rowpane, colpane: colpane};
+ }
+ for (c=editor.context.colpanes[colpane].first; c<=editor.context.colpanes[colpane].last; c++) {
+ coord=editor.context.cellskip[SocialCalc.crToCoord(c,row)];
+ if (!coord || !editor.context.CoordInPane(coord, rowpane, colpane)) // don't count col-spanned cells
+ colindex++;
+ }
+ colindex += 1;
+ }
+ }
+ rowindex += editor.context.rowpanes[rowpane].last - editor.context.rowpanes[rowpane].first + 1 + 1;
+ }
+
+ return null;
+}
+
+//
+// cellcoord = MoveECellWithKey(editor, ch)
+//
+// Processes an arrow key, etc., moving the edit cell.
+// If not a movement key, returns null.
+//
+
+SocialCalc.MoveECellWithKey = function(editor, ch) {
+
+ var coord, row, col, cell;
+ var shifted = false;
+
+ if (!editor.ecell) {
+ return null;
+ }
+
+ if (ch.slice(-7)=="shifted") {
+ ch = ch.slice(0,-7);
+ shifted = true;
+ }
+
+ row = editor.ecell.row;
+ col = editor.ecell.col;
+ cell = editor.context.sheetobj.cells[editor.ecell.coord];
+
+ switch (ch) {
+ case "[adown]":
+ row += (cell && cell.rowspan) || 1;
+ break;
+ case "[aup]":
+ row--;
+ break;
+ case "[pgdn]":
+ row += editor.pageUpDnAmount - 1 + ((cell && cell.rowspan) || 1);
+ break;
+ case "[pgup]":
+ row -= editor.pageUpDnAmount;
+ break;
+ case "[aright]":
+ col += (cell && cell.colspan) || 1;
+ break;
+ case "[aleft]":
+ col--;
+ break;
+ case "[home]":
+ row = 1;
+ col = 1;
+ break;
+ default:
+ return null;
+ }
+
+ if (!editor.range.hasrange) {
+ if (shifted)
+ editor.RangeAnchor();
+ }
+
+ coord = editor.MoveECell(SocialCalc.crToCoord(col, row));
+
+ if (editor.range.hasrange) {
+ if (shifted)
+ editor.RangeExtend();
+ else
+ editor.RangeRemove();
+ }
+
+ return coord;
+
+ }
+
+//
+// cellcoord = MoveECell(editor, newecell)
+//
+// Takes a coordinate and returns the new edit cell coordinate (which may be
+// different if newecell is covered by a span).
+//
+
+SocialCalc.MoveECell = function(editor, newcell) {
+
+ var cell, f;
+
+ var highlights = editor.context.highlights;
+
+ if (editor.ecell) {
+ if (editor.ecell.coord==newcell) return newcell; // already there - don't do anything and don't tell anybody
+ cell=SocialCalc.GetEditorCellElement(editor, editor.ecell.row, editor.ecell.col);
+ delete highlights[editor.ecell.coord];
+ if (editor.range2.hasrange &&
+ editor.ecell.row>=editor.range2.top && editor.ecell.row<=editor.range2.bottom &&
+ editor.ecell.col>=editor.range2.left && editor.ecell.col<=editor.range2.right) {
+ highlights[editor.ecell.coord] = "range2";
+ }
+ editor.UpdateCellCSS(cell, editor.ecell.row, editor.ecell.col);
+ editor.SetECellHeaders(""); // set to regular col/rowname styles
+ }
+ newcell = editor.context.cellskip[newcell] || newcell;
+ editor.ecell = SocialCalc.coordToCr(newcell);
+ editor.ecell.coord = newcell;
+ cell=SocialCalc.GetEditorCellElement(editor, editor.ecell.row, editor.ecell.col);
+ highlights[newcell] = "cursor";
+
+ for (f in editor.MoveECellCallback) { // let others know
+ editor.MoveECellCallback[f](editor);
+ }
+
+ editor.UpdateCellCSS(cell, editor.ecell.row, editor.ecell.col);
+ editor.SetECellHeaders("selected");
+
+ for (f in editor.StatusCallback) { // let status line, etc., know
+ editor.StatusCallback[f].func(editor, "moveecell", newcell, editor.StatusCallback[f].params);
+ }
+
+ if (editor.busy) {
+ editor.ensureecell = true; // wait for when not busy
+ }
+ else {
+ editor.ensureecell = false;
+ editor.EnsureECellVisible();
+ }
+
+ return newcell;
+
+ }
+
+SocialCalc.EnsureECellVisible = function(editor) {
+
+ var vamount = 0;
+ var hamount = 0;
+
+ if (editor.ecell.row > editor.lastnonscrollingrow) {
+ if (editor.ecell.row < editor.firstscrollingrow) {
+ vamount = editor.ecell.row - editor.firstscrollingrow;
+ }
+ else if (editor.ecell.row > editor.lastvisiblerow) {
+ vamount = editor.ecell.row - editor.lastvisiblerow;
+ }
+ }
+ if (editor.ecell.col > editor.lastnonscrollingcol) {
+ if (editor.ecell.col < editor.firstscrollingcol) {
+ hamount = editor.ecell.col - editor.firstscrollingcol;
+ }
+ else if (editor.ecell.col > editor.lastvisiblecol) {
+ hamount = editor.ecell.col- editor.lastvisiblecol;
+ }
+ }
+
+ if (vamount!=0 || hamount!=0) {
+ editor.ScrollRelativeBoth(vamount, hamount);
+ }
+
+ }
+
+SocialCalc.ReplaceCell = function(editor, cell, row, col) {
+
+ var newelement, a;
+ if (!cell) return;
+ newelement = editor.context.RenderCell(row, col, cell.rowpane, cell.colpane, true, null);
+ if (newelement) {
+ // Don't use a real element and replaceChild, which seems to have focus issues with IE, Firefox, and speed issues
+ cell.element.innerHTML = newelement.innerHTML;
+ cell.element.style.cssText = "";
+ cell.element.className = newelement.className;
+ for (a in newelement.style) {
+ if (newelement.style[a]!="cssText")
+ cell.element.style[a] = newelement.style[a];
+ }
+ }
+ }
+
+
+SocialCalc.UpdateCellCSS = function(editor, cell, row, col) {
+
+ var newelement, a;
+ if (!cell) return;
+ newelement = editor.context.RenderCell(row, col, cell.rowpane, cell.colpane, true, null);
+ if (newelement) {
+ cell.element.style.cssText = "";
+ cell.element.className = newelement.className;
+ for (a in newelement.style) {
+ if (newelement.style[a]!="cssText")
+ cell.element.style[a] = newelement.style[a];
+ }
+ }
+ }
+
+
+SocialCalc.SetECellHeaders = function(editor, selected) {
+
+ var ecell = editor.ecell;
+ var context = editor.context;
+
+ var rowpane, colpane, first, last;
+ var rowindex = 0;
+ var colindex = 0;
+ var headercell;
+
+ if (!ecell) return;
+
+ for (rowpane=0; rowpane<context.rowpanes.length; rowpane++) {
+ first = context.rowpanes[rowpane].first;
+ last = context.rowpanes[rowpane].last;
+ if (ecell.row >= first && ecell.row <= last) {
+ headercell = editor.fullgrid.childNodes[1].childNodes[2+rowindex+ecell.row-first].childNodes[0];
+ if (headercell) {
+ if (context.classnames) headercell.className=context.classnames[selected+"rowname"];
+ if (context.explicitStyles) headercell.style.cssText=context.explicitStyles[selected+"rowname"];
+ headercell.style.verticalAlign="top"; // to get around Safari making top of centered row number be
+ // considered top of row (and can't get <row> position in Safari)
+ }
+ }
+ rowindex += last - first + 1 + 1;
+ }
+
+ for (colpane=0; colpane<context.colpanes.length; colpane++) {
+ first = context.colpanes[colpane].first;
+ last = context.colpanes[colpane].last;
+ if (ecell.col >= first && ecell.col <= last) {
+ headercell = editor.fullgrid.childNodes[1].childNodes[1].childNodes[1+colindex+ecell.col-first];
+ if (headercell) {
+ if (context.classnames) headercell.className=context.classnames[selected+"colname"];
+ if (context.explicitStyles) headercell.style.cssText=context.explicitStyles[selected+"colname"];
+ }
+ }
+ colindex += last - first + 1 + 1;
+ }
+ }
+
+//
+// RangeAnchor(editor, ecoord)
+//
+// Sets the anchor of a range to ecoord (or ecell if missing).
+//
+
+SocialCalc.RangeAnchor = function(editor, ecoord) {
+
+ if (editor.range.hasrange) {
+ editor.RangeRemove();
+ }
+
+ editor.RangeExtend(ecoord);
+
+ }
+
+//
+// RangeExtend(editor, ecoord)
+//
+// Sets the other corner of the range to ecoord or, if missing, ecell.
+//
+
+SocialCalc.RangeExtend = function(editor, ecoord) {
+
+ var a, cell, cr, coord, row, col, f;
+
+ var highlights = editor.context.highlights;
+ var range = editor.range;
+ var range2 = editor.range2;
+
+ var ecell;
+ if (ecoord) {
+ ecell = SocialCalc.coordToCr(ecoord);
+ ecell.coord = ecoord;
+ }
+ else ecell = editor.ecell;
+
+ if (!ecell) return; // just in case
+
+ if (!range.hasrange) { // called without RangeAnchor...
+ range.anchorcoord = ecell.coord;
+ range.anchorrow = ecell.row;
+ range.top = ecell.row;
+ range.bottom = ecell.row;
+ range.anchorcol = ecell.col;
+ range.left = ecell.col;
+ range.right = ecell.col;
+ range.hasrange = true;
+ }
+
+ if (range.anchorrow < ecell.row) {
+ range.top = range.anchorrow;
+ range.bottom = ecell.row;
+ }
+ else {
+ range.top = ecell.row;
+ range.bottom = range.anchorrow;
+ }
+ if (range.anchorcol < ecell.col) {
+ range.left = range.anchorcol;
+ range.right = ecell.col;
+ }
+ else {
+ range.left = ecell.col;
+ range.right = range.anchorcol;
+ }
+
+ for (coord in highlights) {
+ switch (highlights[coord]) {
+ case "range":
+ highlights[coord] = "unrange";
+ break;
+ case "range2":
+ highlights[coord] = "unrange2";
+ break;
+ }
+ }
+
+ for (row=range.top; row<=range.bottom; row++) {
+ for (col=range.left; col<=range.right; col++) {
+ coord = SocialCalc.crToCoord(col, row);
+ switch (highlights[coord]) {
+ case "unrange":
+ highlights[coord] = "range";
+ break;
+ case "cursor":
+ break;
+ case "unrange2":
+ default:
+ highlights[coord] = "newrange";
+ break;
+ }
+ }
+ }
+
+ for (row=range2.top; range2.hasrange && row<=range2.bottom; row++) {
+ for (col=range2.left; col<=range2.right; col++) {
+ coord = SocialCalc.crToCoord(col, row);
+ switch (highlights[coord]) {
+ case "unrange2":
+ highlights[coord] = "range2";
+ break;
+ case "range":
+ case "newrange":
+ case "cursor":
+ break;
+ default:
+ highlights[coord] = "newrange2";
+ break;
+ }
+ }
+ }
+
+ for (coord in highlights) {
+
+ switch (highlights[coord]) {
+ case "unrange":
+ delete highlights[coord];
+ break;
+ case "newrange":
+ highlights[coord] = "range";
+ break;
+ case "newrange2":
+ highlights[coord] = "range2";
+ break;
+ case "range":
+ case "range2":
+ case "cursor":
+ continue;
+ }
+
+ cr = SocialCalc.coordToCr(coord);
+ cell = SocialCalc.GetEditorCellElement(editor, cr.row, cr.col);
+ editor.UpdateCellCSS(cell, cr.row, cr.col);
+
+ }
+
+ for (f in editor.RangeChangeCallback) { // let others know
+ editor.RangeChangeCallback[f](editor);
+ }
+
+ // create range/coord string and do status callback
+
+ coord = SocialCalc.crToCoord(editor.range.left, editor.range.top);
+ if (editor.range.left!=editor.range.right || editor.range.top!=editor.range.bottom) { // more than one cell
+ coord += ":" + SocialCalc.crToCoord(editor.range.right, editor.range.bottom);
+ }
+ for (f in editor.StatusCallback) {
+ editor.StatusCallback[f].func(editor, "rangechange", coord, editor.StatusCallback[f].params);
+ }
+
+ return;
+
+ }
+
+//
+// RangeRemove(editor)
+//
+// Turns off the range.
+//
+
+SocialCalc.RangeRemove = function(editor) {
+
+ var cell, cr, coord, row, col, f;
+
+ var highlights = editor.context.highlights;
+ var range = editor.range;
+ var range2 = editor.range2;
+
+ if (!range.hasrange && !range2.hasrange) return;
+
+ for (row=range2.top; range2.hasrange && row<=range2.bottom; row++) {
+ for (col=range2.left; col<=range2.right; col++) {
+ coord = SocialCalc.crToCoord(col, row);
+ switch (highlights[coord]) {
+ case "range":
+ highlights[coord] = "newrange2";
+ break;
+ case "range2":
+ case "cursor":
+ break;
+ default:
+ highlights[coord] = "newrange2";
+ break;
+ }
+ }
+ }
+
+ for (coord in highlights) {
+ switch (highlights[coord]) {
+ case "range":
+ delete highlights[coord];
+ break;
+ case "newrange2":
+ highlights[coord] = "range2";
+ break;
+ case "cursor":
+ continue;
+ }
+ cr = SocialCalc.coordToCr(coord);
+ cell=SocialCalc.GetEditorCellElement(editor, cr.row, cr.col);
+ editor.UpdateCellCSS(cell, cr.row, cr.col);
+ }
+
+ range.hasrange = false;
+
+ for (f in editor.RangeChangeCallback) { // let others know
+ editor.RangeChangeCallback[f](editor);
+ }
+
+ for (f in editor.StatusCallback) {
+ editor.StatusCallback[f].func(editor, "rangechange", "", editor.StatusCallback[f].params);
+ }
+
+ return;
+
+ }
+
+//
+// Range2Remove(editor)
+//
+// Turns off the range2.
+//
+
+SocialCalc.Range2Remove = function(editor) {
+
+ var cell, cr, coord, row, col, f;
+
+ var highlights = editor.context.highlights;
+ var range2 = editor.range2;
+
+ if (!range2.hasrange) return;
+
+ for (coord in highlights) {
+ switch (highlights[coord]) {
+ case "range2":
+ delete highlights[coord];
+ break;
+ case "range":
+ case "cursor":
+ continue;
+ }
+ cr = SocialCalc.coordToCr(coord);
+ cell=SocialCalc.GetEditorCellElement(editor, cr.row, cr.col);
+ editor.UpdateCellCSS(cell, cr.row, cr.col);
+ }
+
+ range2.hasrange = false;
+
+ return;
+
+ }
+
+//
+// FitToEditTable(editor)
+//
+// Figure out (through column width declarations and approximation of pixels per row)
+// how many rendered rows and columns you need to be at least a little larger than
+// the editor's editing area.
+//
+
+SocialCalc.FitToEditTable = function(editor) {
+
+ var colnum, colname, colwidth, totalwidth, totalrows, rowpane, needed;
+
+ var context=editor.context;
+ var sheetobj=context.sheetobj;
+ var sheetcolattribs=sheetobj.colattribs;
+
+ // Calculate column width data
+
+ totalwidth=context.showRCHeaders ? context.rownamewidth-0 : 0;
+ for (colpane=0; colpane<context.colpanes.length-1; colpane++) { // Get width of all but last pane
+ for (colnum=context.colpanes[colpane].first; colnum<=context.colpanes[colpane].last; colnum++) {
+ colname=SocialCalc.rcColname(colnum);
+ colwidth = sheetobj.colattribs.width[colname] || sheetobj.attribs.defaultcolwidth || SocialCalc.Constants.defaultColWidth;
+ if (colwidth=="blank" || colwidth=="auto") colwidth="";
+ totalwidth+=(colwidth && ((colwidth-0)>0)) ? (colwidth-0) : 10;
+ }
+ }
+
+ for (colnum=context.colpanes[colpane].first; colnum<=10000; colnum++) { //!!! max for safety, but makes that col max!!!
+ colname=SocialCalc.rcColname(colnum);
+ colwidth = sheetobj.colattribs.width[colname] || sheetobj.attribs.defaultcolwidth || SocialCalc.Constants.defaultColWidth;
+ if (colwidth=="blank" || colwidth=="auto") colwidth="";
+ totalwidth+=(colwidth && ((colwidth-0)>0)) ? (colwidth-0) : 10;
+ if (totalwidth > editor.tablewidth) break;
+ }
+
+ context.colpanes[colpane].last = colnum;
+
+ // Calculate row height data
+
+ totalrows=context.showRCHeaders ? 1 : 0;
+ for (rowpane=0; rowpane<context.rowpanes.length-1; rowpane++) { // count all panes but last one
+ totalrows += context.rowpanes[rowpane].last - context.rowpanes[rowpane].first + 1;
+ }
+
+ needed = editor.tableheight - totalrows * context.pixelsPerRow; // estimate amount needed
+
+ context.rowpanes[rowpane].last = context.rowpanes[rowpane].first + Math.floor(needed / context.pixelsPerRow) + 1;
+
+ }
+
+//
+// CalculateEditorPositions(editor)
+//
+// Calculate the screen positions and other values of various editing elements
+// These values change and need to be recomputed when the pane first/last or cell contents change,
+// as well as new column widths, etc.
+//
+// Note: Only call this after the grid has been rendered! You may have to wait for a timeout...
+//
+
+SocialCalc.CalculateEditorPositions = function(editor) {
+
+ var rowpane, colpane, i;
+
+ editor.gridposition = SocialCalc.GetElementPosition(editor.griddiv);
+ editor.headposition =
+ SocialCalc.GetElementPosition(editor.griddiv.firstChild.lastChild.childNodes[2].childNodes[1]); // 3rd tr 2nd td
+
+ editor.rowpositions = [];
+ for (rowpane=0; rowpane<editor.context.rowpanes.length; rowpane++) {
+ editor.CalculateRowPositions(rowpane, editor.rowpositions, editor.rowheight);
+ }
+ for (i=0; i<editor.rowpositions.length; i++) {
+ if (editor.rowpositions[i]>editor.gridposition.top+editor.tableheight) break;
+ }
+ editor.lastvisiblerow = i-1;
+
+ editor.colpositions = [];
+ for (colpane=0; colpane<editor.context.colpanes.length; colpane++) {
+ editor.CalculateColPositions(colpane, editor.colpositions, editor.colwidth);
+ }
+ for (i=0; i<editor.colpositions.length; i++) {
+ if (editor.colpositions[i]>editor.gridposition.left+editor.tablewidth) break;
+ }
+ editor.lastvisiblecol = i-1;
+
+ editor.firstscrollingrow = editor.context.rowpanes[editor.context.rowpanes.length-1].first;
+ editor.firstscrollingrowtop = editor.rowpositions[editor.firstscrollingrow] || editor.headposition.top;
+ editor.lastnonscrollingrow = editor.context.rowpanes.length-1 > 0 ?
+ editor.context.rowpanes[editor.context.rowpanes.length-2].last : 0;
+ editor.firstscrollingcol = editor.context.colpanes[editor.context.colpanes.length-1].first;
+ editor.firstscrollingcolleft = editor.colpositions[editor.firstscrollingcol] || editor.headposition.left;
+ editor.lastnonscrollingcol = editor.context.colpanes.length-1 > 0 ?
+ editor.context.colpanes[editor.context.colpanes.length-2].last : 0;
+
+ // Now do the table controls
+
+ editor.verticaltablecontrol.ComputeTableControlPositions();
+ editor.horizontaltablecontrol.ComputeTableControlPositions();
+ }
+
+//
+// ScheduleRender(editor)
+//
+// Do a series of timeouts to render the sheet, wait for background layout and
+// rendering by the browser, and then update editor visuals, sliders, etc.
+//
+
+SocialCalc.ScheduleRender = function(editor) {
+
+ if (editor.timeout) window.clearTimeout(editor.timeout); // in case called more than once, just use latest
+
+ SocialCalc.EditorSheetStatusCallback(null, "schedrender", null, editor);
+ SocialCalc.EditorStepInfo.editor = editor;
+ editor.timeout = window.setTimeout(SocialCalc.DoRenderStep, 1);
+
+ }
+
+// DoRenderStep()
+//
+
+SocialCalc.DoRenderStep = function() {
+
+ var editor = SocialCalc.EditorStepInfo.editor;
+
+ editor.timeout = null;
+
+ editor.EditorRenderSheet();
+
+ SocialCalc.EditorSheetStatusCallback(null, "renderdone", null, editor);
+
+ SocialCalc.EditorSheetStatusCallback(null, "schedposcalc", null, editor);
+
+ editor.timeout = window.setTimeout(SocialCalc.DoPositionCalculations, 1);
+
+ }
+
+//
+// SocialCalc.SchedulePositionCalculations(editor)
+//
+
+SocialCalc.SchedulePositionCalculations = function(editor) {
+
+ SocialCalc.EditorStepInfo.editor = editor;
+
+ SocialCalc.EditorSheetStatusCallback(null, "schedposcalc", null, editor);
+
+ editor.timeout = window.setTimeout(SocialCalc.DoPositionCalculations, 1);
+
+ }
+
+// DoPositionCalculations(editor)
+//
+// Update editor visuals, sliders, etc.
+//
+// Note: Only call this after the DOM objects have been modified and rendered!
+//
+
+SocialCalc.DoPositionCalculations = function() {
+
+ var editor = SocialCalc.EditorStepInfo.editor;
+
+ editor.timeout = null;
+
+ editor.CalculateEditorPositions();
+ editor.verticaltablecontrol.PositionTableControlElements();
+ editor.horizontaltablecontrol.PositionTableControlElements();
+
+ SocialCalc.EditorSheetStatusCallback(null, "doneposcalc", null, editor);
+
+ if (editor.ensureecell && editor.ecell && !editor.deferredCommands.length) { // don't do if deferred cmd to execute
+ editor.ensureecell = false;
+ editor.EnsureECellVisible(); // this could cause another redisplay
+ }
+
+//!!! Need to now check to see if this positioned controls out of the editing area
+//!!! (such as when there is a large wrapped cell and it pushes the pane boundary too far down).
+
+ }
+
+SocialCalc.CalculateRowPositions = function(editor, panenum, positions, sizes) {
+
+ var toprow, rowpane, rownum, offset, trowobj, cellposition;
+
+ var context=editor.context;
+ var sheetobj=context.sheetobj;
+
+ var tbodyobj;
+
+ if (!context.showRCHeaders) throw("Needs showRCHeaders=true");
+
+ tbodyobj=editor.fullgrid.lastChild;
+
+ // Calculate start of this pane as row in this table:
+
+ toprow = 2;
+ for (rowpane=0; rowpane<panenum; rowpane++) {
+ toprow += context.rowpanes[rowpane].last - context.rowpanes[rowpane].first + 2; // skip pane and spacing row
+ }
+
+ offset = 0;
+ for (rownum=context.rowpanes[rowpane].first; rownum<=context.rowpanes[rowpane].last; rownum++) {
+ trowobj = tbodyobj.childNodes[toprow+offset];
+ offset++;
+ cellposition = SocialCalc.GetElementPosition(trowobj.firstChild);
+
+// Safari has problem: If a cell in the row is high, cell 1 is centered and it returns top of centered part
+// but if you get position of row element, it always returns the same value (not the row's)
+// So we require row number to be vertical aligned to top
+
+ if (!positions[rownum]) {
+ positions[rownum] = cellposition.top; // first one takes precedence
+ sizes[rownum] = trowobj.firstChild.offsetHeight;
+ }
+ }
+
+ return;
+
+ }
+
+SocialCalc.CalculateColPositions = function(editor, panenum, positions, sizes) {
+
+ var leftcol, colpane, colnum, offset, trowobj, cellposition;
+
+ var context=editor.context;
+ var sheetobj=context.sheetobj;
+
+ var tbodyobj;
+
+ if (!context.showRCHeaders) throw("Needs showRCHeaders=true");
+
+ tbodyobj=editor.fullgrid.lastChild;
+
+ // Calculate start of this pane as column in this table:
+
+ leftcol = 1;
+ for (colpane=0; colpane<panenum; colpane++) {
+ leftcol += context.colpanes[colpane].last - context.colpanes[colpane].first + 2; // skip pane and spacing col
+ }
+
+ trowobj = tbodyobj.childNodes[1]; // get heading row, which has all columns
+ offset = 0;
+ for (colnum=context.colpanes[colpane].first; colnum<=context.colpanes[colpane].last; colnum++) {
+ cellposition = SocialCalc.GetElementPosition(trowobj.childNodes[leftcol+offset]);
+ if (!positions[colnum]) {
+ positions[colnum] = cellposition.left; // first one takes precedence
+ if (trowobj.childNodes[leftcol+offset]) {
+ sizes[colnum] = trowobj.childNodes[leftcol+offset].offsetWidth;
+ }
+ }
+ offset++;
+ }
+
+ return;
+
+ }
+
+
+// ScrollRelative(editor, vertical, amount)
+//
+// If vertical true, scrolls up(-)/down(+), else left(-)/right(+)
+
+SocialCalc.ScrollRelative = function(editor, vertical, amount) {
+
+ if (vertical) {
+ editor.ScrollRelativeBoth(amount, 0);
+ }
+ else {
+ editor.ScrollRelativeBoth(0, amount);
+ }
+ return;
+
+ }
+
+// ScrollRelativeBoth(editor, vamount, hamount)
+//
+// Does both with one render
+
+SocialCalc.ScrollRelativeBoth = function(editor, vamount, hamount) {
+
+ var context=editor.context;
+
+ var vplen=context.rowpanes.length;
+ var vlimit = vplen>1 ? context.rowpanes[vplen-2].last+1 : 1; // don't scroll past here
+ if (context.rowpanes[vplen-1].first+vamount < vlimit) { // limit amount
+ vamount = (-context.rowpanes[vplen-1].first) + vlimit;
+ }
+
+ var hplen=context.colpanes.length;
+ var hlimit = hplen>1 ? context.colpanes[hplen-2].last+1 : 1; // don't scroll past here
+ if (context.colpanes[hplen-1].first+hamount < hlimit) { // limit amount
+ hamount = (-context.colpanes[hplen-1].first) + hlimit;
+ }
+
+ if ((vamount==1 || vamount==-1) && hamount==0) { // special case quick scrolls
+ if (vamount==1) {
+ editor.ScrollTableUpOneRow();
+ }
+ else {
+ editor.ScrollTableDownOneRow();
+ }
+ if (editor.ecell) editor.SetECellHeaders("selected");
+ editor.SchedulePositionCalculations();
+ return;
+ }
+
+ // Do a gross move and render
+
+ if (vamount!=0 || hamount!=0) {
+ context.rowpanes[vplen-1].first += vamount;
+ context.rowpanes[vplen-1].last += vamount;
+ context.colpanes[hplen-1].first += hamount;
+ context.colpanes[hplen-1].last += hamount;
+ editor.FitToEditTable();
+ editor.ScheduleRender();
+ }
+
+ }
+
+
+// PageRelative(editor, vertical, direction)
+//
+// If vertical true, pages up(direction is -)/down(+), else left(-)/right(+)
+
+SocialCalc.PageRelative = function(editor, vertical, direction) {
+
+ var context=editor.context;
+ var panes=vertical ? "rowpanes" : "colpanes";
+ var lastpane=context[panes][context[panes].length-1];
+ var lastvisible=vertical ? "lastvisiblerow" : "lastvisiblecol";
+ var sizearray=vertical ? editor.rowheight : editor.colwidth;
+ var defaultsize=vertical ? SocialCalc.Constants.defaultAssumedRowHeight : SocialCalc.Constants.defaultColWidth;
+ var size, newfirst, totalsize, current;
+
+ if (direction > 0) { // down/right
+ newfirst = editor[lastvisible];
+ if (newfirst == lastpane.first) newfirst += 1; // move at least one
+ }
+ else {
+ if (vertical) { // calculate amount to scroll
+ totalsize = editor.tableheight - (editor.firstscrollingrowtop - editor.gridposition.top);
+ }
+ else {
+ totalsize = editor.tablewidth - (editor.firstscrollingcolleft - editor.gridposition.left);
+ }
+ totalsize -= sizearray[editor[lastvisible]] > 0 ? sizearray[editor[lastvisible]] : defaultsize;
+
+ for (newfirst=lastpane.first-1; newfirst>0; newfirst--) {
+ size = sizearray[newfirst] > 0 ? sizearray[newfirst] : defaultsize;
+ if (totalsize < size) break;
+ totalsize -= size;
+ }
+
+ current = lastpane.first;
+ if (newfirst >= current) newfirst = current-1; // move at least 1
+ if (newfirst < 1) newfirst = 1;
+ }
+
+ lastpane.first = newfirst;
+ lastpane.last = newfirst+1;
+ editor.LimitLastPanes();
+ editor.FitToEditTable();
+ editor.ScheduleRender();
+
+ }
+
+// LimitLastPanes(editor)
+//
+// Makes sure that the "first" of the last panes isn't before the last of the previous pane
+//
+
+SocialCalc.LimitLastPanes = function(editor) {
+
+ var context=editor.context;
+ var plen;
+
+ plen = context.rowpanes.length;
+ if (plen>1 && context.rowpanes[plen-1].first <= context.rowpanes[plen-2].last)
+ context.rowpanes[plen-1].first = context.rowpanes[plen-2].last+1;
+
+ plen = context.colpanes.length;
+ if (plen>1 && context.colpanes[plen-1].first <= context.colpanes[plen-2].last)
+ context.colpanes[plen-1].first = context.colpanes[plen-2].last+1;
+
+ }
+
+SocialCalc.ScrollTableUpOneRow = function(editor) {
+
+ var toprow, rowpane, rownum, colnum, colpane, cell, oldrownum, maxspan, newbottomrow, newrow, oldchild, bottomrownum;
+ var rowneedsrefresh={};
+
+ var context=editor.context;
+ var sheetobj=context.sheetobj;
+ var tableobj=editor.fullgrid;
+
+ var tbodyobj;
+
+ tbodyobj=tableobj.lastChild;
+
+ toprow = context.showRCHeaders ? 2 : 1;
+ for (rowpane=0; rowpane<context.rowpanes.length-1; rowpane++) {
+ toprow += context.rowpanes[rowpane].last - context.rowpanes[rowpane].first + 2; // skip pane and spacing row
+ }
+
+ tbodyobj.removeChild(tbodyobj.childNodes[toprow]);
+
+ context.rowpanes[rowpane].first++;
+ context.rowpanes[rowpane].last++;
+ editor.FitToEditTable();
+ context.CalculateColWidthData(); // Just in case, since normally done in RenderSheet
+
+ newbottomrow = context.RenderRow(context.rowpanes[rowpane].last, rowpane);
+ tbodyobj.appendChild(newbottomrow);
+
+ // if scrolled off a row with starting rowspans, replace rows for the largest rowspan
+
+ maxrowspan = 1;
+ oldrownum=context.rowpanes[rowpane].first - 1;
+
+ for (colpane=0; colpane<context.colpanes.length; colpane++) {
+ for (colnum=context.colpanes[colpane].first; colnum<=context.colpanes[colpane].last; colnum++) {
+ coord=SocialCalc.crToCoord(colnum, oldrownum);
+ if (context.cellskip[coord]) continue;
+ cell=sheetobj.cells[coord];
+ if (cell && cell.rowspan>maxrowspan) maxrowspan=cell.rowspan;
+ }
+ }
+
+ if (maxrowspan>1) {
+ for (rownum=1; rownum<maxrowspan; rownum++) {
+ if (rownum+oldrownum >= context.rowpanes[rowpane].last) break;
+ newrow=context.RenderRow(rownum+oldrownum, rowpane);
+ oldchild=tbodyobj.childNodes[toprow+rownum-1];
+ tbodyobj.replaceChild(newrow,oldchild);
+ }
+ }
+
+ // if added a row that includes rowspans from above, update the size of those to include new row
+
+ bottomrownum=context.rowpanes[rowpane].last;
+
+ for (colpane=0; colpane<context.colpanes.length; colpane++) {
+ for (colnum=context.colpanes[colpane].first; colnum<=context.colpanes[colpane].last; colnum++) {
+ coord=context.cellskip[SocialCalc.crToCoord(colnum, bottomrownum)];
+ if (!coord) continue; // only look at spanned cells
+ rownum=context.coordToCR[coord].row-0;
+ if (rownum==context.rowpanes[rowpane].last ||
+ rownum<context.rowpanes[rowpane].first) continue; // this row (colspan) or starts above pane
+ cell=sheetobj.cells[coord];
+ if (cell && cell.rowspan>1) rowneedsrefresh[rownum]=true; // remember row num to update
+ }
+ }
+
+ for (rownum in rowneedsrefresh) {
+ newrow=context.RenderRow(rownum, rowpane);
+ oldchild=tbodyobj.childNodes[(toprow+(rownum-context.rowpanes[rowpane].first))];
+ tbodyobj.replaceChild(newrow,oldchild);
+ }
+
+ return tableobj;
+ }
+
+SocialCalc.ScrollTableDownOneRow = function(editor) {
+
+ var toprow, rowpane, rownum, colnum, colpane, cell, newrownum, maxspan, newbottomrow, newrow, oldchild, bottomrownum;
+ var rowneedsrefresh={};
+
+ var context=editor.context;
+ var sheetobj=context.sheetobj;
+ var tableobj=editor.fullgrid;
+
+ var tbodyobj;
+
+ tbodyobj=tableobj.lastChild;
+
+ toprow = context.showRCHeaders ? 2 : 1;
+ for (rowpane=0; rowpane<context.rowpanes.length-1; rowpane++) {
+ toprow += context.rowpanes[rowpane].last - context.rowpanes[rowpane].first + 2; // skip pane and spacing row
+ }
+
+ tbodyobj.removeChild(tbodyobj.childNodes[toprow+(context.rowpanes[rowpane].last-context.rowpanes[rowpane].first)]);
+
+ context.rowpanes[rowpane].first--;
+ context.rowpanes[rowpane].last--;
+ editor.FitToEditTable();
+ context.CalculateColWidthData(); // Just in case, since normally done in RenderSheet
+
+ newrow = context.RenderRow(context.rowpanes[rowpane].first, rowpane);
+ tbodyobj.insertBefore(newrow, tbodyobj.childNodes[toprow]);
+
+ // if inserted a row with starting rowspans, replace rows for the largest rowspan
+
+ maxrowspan = 1;
+ newrownum=context.rowpanes[rowpane].first;
+
+ for (colpane=0; colpane<context.colpanes.length; colpane++) {
+ for (colnum=context.colpanes[colpane].first; colnum<=context.colpanes[colpane].last; colnum++) {
+ coord=SocialCalc.crToCoord(colnum, newrownum);
+ if (context.cellskip[coord]) continue;
+ cell=sheetobj.cells[coord];
+ if (cell && cell.rowspan>maxrowspan) maxrowspan=cell.rowspan;
+ }
+ }
+
+ if (maxrowspan>1) {
+ for (rownum=1; rownum<maxrowspan; rownum++) {
+ if (rownum+newrownum > context.rowpanes[rowpane].last) break;
+ newrow=context.RenderRow(rownum+newrownum, rowpane);
+ oldchild=tbodyobj.childNodes[toprow+rownum];
+ tbodyobj.replaceChild(newrow,oldchild);
+ }
+ }
+
+ // if last row now includes rowspans or rowspans from above, update the size of those to remove deleted row
+
+ bottomrownum=context.rowpanes[rowpane].last;
+
+ for (colpane=0; colpane<context.colpanes.length; colpane++) {
+ for (colnum=context.colpanes[colpane].first; colnum<=context.colpanes[colpane].last; colnum++) {
+ coord=SocialCalc.crToCoord(colnum, bottomrownum);
+ cell=sheetobj.cells[coord];
+ if (cell && cell.rowspan>1) {
+ rowneedsrefresh[bottomrownum]=true; // need to update this row
+ continue;
+ }
+ coord=context.cellskip[SocialCalc.crToCoord(colnum, bottomrownum)];
+ if (!coord) continue; // only look at spanned cells
+ rownum=context.coordToCR[coord].row-0;
+ if (rownum==bottomrownum ||
+ rownum<context.rowpanes[rowpane].first) continue; // this row (colspan) or starts above pane
+ cell=sheetobj.cells[coord];
+ if (cell && cell.rowspan>1) rowneedsrefresh[rownum]=true; // remember row num to update
+ }
+ }
+
+ for (rownum in rowneedsrefresh) {
+ newrow=context.RenderRow(rownum, rowpane);
+ oldchild=tbodyobj.childNodes[(toprow+(rownum-context.rowpanes[rowpane].first))];
+ tbodyobj.replaceChild(newrow,oldchild);
+ }
+
+ return tableobj;
+ }
+
+
+// *************************************
+//
+// InputBox class:
+//
+// This class deals with the text box for editing cell contents.
+// It mainly controls a user input box for typed content and is used to interact with
+// the keyboard code, etc.
+//
+// You can use this inside a formula bar control of some sort.
+// You create this after you have created a table editor object (but not necessarily
+// done the CreateTableEditor method).
+//
+// When the user starts typing text, or double-clicks on a cell, this object
+// comes into play.
+//
+// The element given when this is first constructed should be an input HTMLElement or
+// something that acts like one. Check the code here to see what is done to it.
+//
+// *************************************
+
+SocialCalc.InputBox = function(element, editor) {
+
+ if (!element) return; // invoked without enough data to work
+
+ this.element = element; // the input element associated with this InputBox
+ this.editor = editor; // the TableEditor this belongs to
+ this.inputEcho = null;
+
+ editor.inputBox = this;
+
+ element.onmousedown = SocialCalc.InputBoxOnMouseDown;
+
+ editor.MoveECellCallback.formulabar = function(e){
+ if (e.state!="start") return; // if not in normal keyboard mode don't replace formula bar
+ editor.inputBox.DisplayCellContents(e.ecell.coord);
+ };
+ }
+
+
+// Methods:
+
+SocialCalc.InputBox.prototype.DisplayCellContents = function(coord) {SocialCalc.InputBoxDisplayCellContents(this, coord);};
+SocialCalc.InputBox.prototype.ShowInputBox = function(show) {this.editor.inputEcho.ShowInputEcho(show);};
+SocialCalc.InputBox.prototype.GetText = function() {return this.element.value;};
+SocialCalc.InputBox.prototype.SetText = function(newtext) {
+ this.element.value=newtext;
+ this.editor.inputEcho.SetText(newtext+"_");
+ };
+SocialCalc.InputBox.prototype.Focus = function() {SocialCalc.InputBoxFocus(this);};
+SocialCalc.InputBox.prototype.Blur = function() {return this.element.blur();};
+SocialCalc.InputBox.prototype.Select = function(t) {
+ switch (t) {
+ case "end":
+ if (this.element.selectionStart!=undefined) {
+ this.element.selectionStart=this.element.value.length;
+ this.element.selectionEnd=this.element.value.length;
+ }
+ break;
+ }
+ };
+
+// Functions:
+
+//
+// SocialCalc.InputBoxDisplayCellContents(inputbox, coord)
+//
+// Sets input box to the contents of the specified cell (or ecell if null).
+//
+
+SocialCalc.InputBoxDisplayCellContents = function(inputbox, coord) {
+
+ var scc = SocialCalc.Constants;
+
+ if (!coord) coord = inputbox.editor.ecell.coord;
+ var text = SocialCalc.GetCellContents(inputbox.editor.context.sheetobj, coord);
+ if (text.indexOf("\n")!=-1) {
+ text = scc.s_inputboxdisplaymultilinetext;
+ inputbox.element.disabled = true;
+ }
+ else {
+ inputbox.element.disabled = false;
+ }
+ inputbox.SetText(text);
+
+ }
+
+//
+// SocialCalc.InputBoxFocus(inputbox)
+//
+// Call this to have the input box get the focus and respond to keystrokes
+// but still pass them off to SocialCalc.ProcessKey.
+//
+
+SocialCalc.InputBoxFocus = function(inputbox) {
+
+ inputbox.element.focus();
+ var editor = inputbox.editor;
+ editor.state = "input";
+ var wval = editor.workingvalues;
+ wval.partialexpr = "";
+ wval.ecoord = editor.ecell.coord;
+ wval.erow = editor.ecell.row;
+ wval.ecol = editor.ecell.col;
+
+ };
+
+//
+// SocialCalc.InputBoxOnMouseDown(e)
+//
+// This is called when the input box gets the focus. It then responds to keystrokes
+// and pass them off to SocialCalc.ProcessKey, but in a different editing state.
+//
+
+SocialCalc.InputBoxOnMouseDown = function(e) {
+
+ var editor = SocialCalc.Keyboard.focusTable; // get TableEditor doing keyboard stuff
+ if (!editor) return true; // we're not handling it -- let browser do default
+ var wval = editor.workingvalues;
+
+ switch (editor.state) {
+ case "start":
+ editor.state="inputboxdirect";
+ wval.partialexpr = "";
+ wval.ecoord = editor.ecell.coord;
+ wval.erow = editor.ecell.row;
+ wval.ecol = editor.ecell.col;
+ editor.inputEcho.ShowInputEcho(true);
+ break;
+
+ case "input":
+ wval.partialexpr = ""; // make sure not pointing
+ editor.MoveECell(wval.ecoord);
+ editor.state="inputboxdirect";
+ SocialCalc.KeyboardFocus(); // may have come here from outside of grid
+ break;
+
+ case "inputboxdirect":
+ break;
+ }
+ }
+
+
+// *************************************
+//
+// InputEcho class:
+//
+// This object creates and controls an element that echos what's in the InputBox during editing
+// It is draggable.
+//
+// *************************************
+
+SocialCalc.InputEcho = function(editor) {
+
+ var scc = SocialCalc.Constants;
+
+ this.editor = editor; // the TableEditor this belongs to
+ this.text = ""; // current value of what is displayed
+ this.interval = null; // timer handle
+
+ this.container = null; // element containing main echo as well as prompt line
+ this.main = null; // main echo area
+ this.prompt = null;
+
+ this.functionbox = null; // function chooser dialog
+
+ this.container = document.createElement("div");
+ SocialCalc.setStyles(this.container, "display:none;position:absolute;zIndex:10;");
+
+ this.main = document.createElement("div");
+ if (scc.defaultInputEchoClass) this.main.className = scc.defaultInputEchoClass;
+ if (scc.defaultInputEchoStyle) SocialCalc.setStyles(this.main, scc.defaultInputEchoStyle);
+ this.main.innerHTML = "&nbsp;";
+
+ this.container.appendChild(this.main);
+
+ this.prompt = document.createElement("div");
+ if (scc.defaultInputEchoPromptClass) this.prompt.className = scc.defaultInputEchoPromptClass;
+ if (scc.defaultInputEchoPromptStyle) SocialCalc.setStyles(this.prompt, scc.defaultInputEchoPromptStyle);
+ this.prompt.innerHTML = "";
+
+ this.container.appendChild(this.prompt);
+
+ SocialCalc.DragRegister(this.main, true, true, {MouseDown: SocialCalc.DragFunctionStart, MouseMove: SocialCalc.DragFunctionPosition,
+ MouseUp: SocialCalc.DragFunctionPosition,
+ Disabled: null, positionobj: this.container});
+
+ editor.toplevel.appendChild(this.container);
+
+ }
+
+// Methods:
+
+SocialCalc.InputEcho.prototype.ShowInputEcho = function(show) {return SocialCalc.ShowInputEcho(this, show);};
+SocialCalc.InputEcho.prototype.SetText = function(str) {return SocialCalc.SetInputEchoText(this, str);};
+
+// Functions:
+
+SocialCalc.ShowInputEcho = function(inputecho, show) {
+
+ var cell, position;
+ var editor = inputecho.editor;
+
+ if (!editor) return;
+
+ if (show) {
+ cell=SocialCalc.GetEditorCellElement(editor, editor.ecell.row, editor.ecell.col);
+ if (cell) {
+ position = SocialCalc.GetElementPosition(cell.element);
+ inputecho.container.style.left = (position.left-1)+"px";
+ inputecho.container.style.top = (position.top-1)+"px";
+ }
+ inputecho.container.style.display = "block";
+ if (inputecho.interval) window.clearInterval(inputecho.interval); // just in case
+ inputecho.interval = window.setInterval(SocialCalc.InputEchoHeartbeat, 50);
+ }
+ else {
+ if (inputecho.interval) window.clearInterval(inputecho.interval);
+ inputecho.container.style.display = "none";
+ }
+
+ }
+
+SocialCalc.SetInputEchoText = function(inputecho, str) {
+
+ var scc = SocialCalc.Constants;
+ var fname, fstr;
+ var newstr = SocialCalc.special_chars(str);
+ newstr = newstr.replace(/\n/g,"<br>");
+
+ if (inputecho.text != newstr) {
+ inputecho.main.innerHTML = newstr;
+ inputecho.text = newstr;
+ }
+
+ var parts = str.match(/.*[\+\-\*\/\&\^\<\>\=\,\(]([A-Za-z][A-ZA-z]\w*?)\([^\)]*$/);
+ if (str.charAt(0)=="=" && parts) {
+ fname = parts[1].toUpperCase();
+ if (SocialCalc.Formula.FunctionList[fname]) {
+ SocialCalc.Formula.FillFunctionInfo(); // make sure filled
+ fstr = SocialCalc.special_chars(fname+"("+SocialCalc.Formula.FunctionArgString(fname)+")");
+ }
+ else {
+ fstr = scc.ietUnknownFunction+fname;
+ }
+ if (inputecho.prompt.innerHTML != fstr) {
+ inputecho.prompt.innerHTML = fstr;
+ inputecho.prompt.style.display = "block";
+ }
+ }
+ else if (inputecho.prompt.style.display != "none") {
+ inputecho.prompt.innerHTML = "";
+ inputecho.prompt.style.display = "none";
+ }
+
+ }
+
+SocialCalc.InputEchoHeartbeat = function() {
+
+ var editor = SocialCalc.Keyboard.focusTable; // get TableEditor doing keyboard stuff
+ if (!editor) return true; // we're not handling it -- let browser do default
+
+ editor.inputEcho.SetText(editor.inputBox.GetText()+"_");
+
+ }
+
+SocialCalc.InputEchoMouseDown = function(e) {
+ var event = e || window.event;
+
+ var editor = SocialCalc.Keyboard.focusTable; // get TableEditor doing keyboard stuff
+ if (!editor) return true; // we're not handling it -- let browser do default
+
+// if (event.stopPropagation) event.stopPropagation(); // DOM Level 2
+// else event.cancelBubble = true; // IE 5+
+// if (event.preventDefault) event.preventDefault(); // DOM Level 2
+// else event.returnValue = false; // IE 5+
+
+ editor.inputBox.element.focus();
+
+// return false;
+ };
+
+
+// *************************************
+//
+// TableControl class:
+//
+// This class deals with the horizontal and verical scrollbars and pane sliders.
+//
+// +--------------+
+// | Endcap |
+// +- - - - - - - +
+// | |
+// +--------------+
+// | Pane Slider |
+// +--------------+
+// | |
+// | Less Button |
+// | |
+// +--------------+
+// | Scroll Area |
+// | |
+// | |
+// +--------------+
+// | Thumb |
+// +--------------+
+// | |
+// +--------------+
+// | |
+// | More Button |
+// | |
+// +--------------+
+//
+// *************************************
+
+SocialCalc.TableControl = function(editor, vertical, size) {
+
+ var scc = SocialCalc.Constants;
+
+ this.editor = editor; // the TableEditor this belongs to
+
+ this.vertical = vertical; // true if vertical control, false if horizontal
+ this.size = size; // length in pixels
+
+ this.main = null; // main element containing all the others
+ this.endcap = null; // the area at the top/left between the end and the pane slider
+ this.paneslider = null; // the slider to adjust the pane split
+ this.lessbutton = null; // the top/left scroll button
+ this.morebutton = null; // the bottom/right scroll button
+ this.scrollarea = null; // the area between the scroll buttons
+ this.thumb = null; // the sliding thing in the scrollarea
+
+ // computed position values:
+
+ this.controlborder = null; // left or top screen position for vertical or horizontal control
+ this.endcapstart = null; // top or left screen position for vertical or horizontal control
+ this.panesliderstart = null;
+ this.lessbuttonstart = null;
+ this.morebuttonstart = null;
+ this.scrollareastart = null;
+ this.scrollareaend = null;
+ this.scrollareasize = null;
+ this.thumbpos = null;
+
+ // constants:
+
+ this.controlthickness = scc.defaultTableControlThickness; // other dimension of complete control in pixels
+ this.sliderthickness = scc.defaultTCSliderThickness;
+ this.buttonthickness = scc.defaultTCButtonThickness;
+ this.thumbthickness = scc.defaultTCThumbThickness;
+ this.minscrollingpanesize = this.buttonthickness+this.buttonthickness+this.thumbthickness+20; // the 20 is to leave a little space
+
+ }
+
+// Methods:
+
+SocialCalc.TableControl.prototype.CreateTableControl = function() {return SocialCalc.CreateTableControl(this);};
+SocialCalc.TableControl.prototype.PositionTableControlElements = function() {SocialCalc.PositionTableControlElements(this);};
+SocialCalc.TableControl.prototype.ComputeTableControlPositions = function() {SocialCalc.ComputeTableControlPositions(this);};
+
+// Functions:
+
+SocialCalc.CreateTableControl = function(control) {
+
+ var s, functions, params;
+ var AssignID = SocialCalc.AssignID;
+ var setStyles = SocialCalc.setStyles;
+ var scc = SocialCalc.Constants;
+ var TooltipRegister = function(element, etype, vh) {
+ if (scc["s_"+etype+"Tooltip"+vh]) {
+ SocialCalc.TooltipRegister(element, scc["s_"+etype+"Tooltip"+vh], null);
+ }
+ }
+
+ var imageprefix = control.editor.imageprefix;
+ var vh = control.vertical ? "v" : "h";
+
+ control.main = document.createElement("div");
+ s = control.main.style;
+ s.height = (control.vertical ? control.size : control.controlthickness)+"px";
+ s.width = (control.vertical ? control.controlthickness : control.size)+"px";
+ s.zIndex = 0;
+ setStyles(control.main, scc.TCmainStyle);
+ s.backgroundImage="url("+imageprefix+"main-"+vh+".gif)";
+ if (scc.TCmainClass) control.main.className = scc.TCmainClass;
+
+ control.main.style.display="none"; // wait for layout
+
+ control.endcap = document.createElement("div");
+ s = control.endcap.style;
+ s.height = control.controlthickness+"px";
+ s.width = control.controlthickness+"px";
+ s.zIndex = 1;
+ s.overflow = "hidden"; // IE will make the DIV at least font-size height...so use this
+ s.position = "absolute";
+ setStyles(control.endcap, scc.TCendcapStyle);
+ s.backgroundImage="url("+imageprefix+"endcap-"+vh+".gif)";
+ if (scc.TCendcapClass) control.endcap.className = scc.TCendcapClass;
+ AssignID(control.editor, control.endcap, "endcap"+vh);
+
+ control.main.appendChild(control.endcap);
+
+ control.paneslider = document.createElement("div");
+ s = control.paneslider.style;
+ s.height = (control.vertical ? control.sliderthickness : control.controlthickness)+"px";
+ s.overflow = "hidden"; // IE will make the DIV at least font-size height...so use this
+ s.width = (control.vertical ? control.controlthickness : control.sliderthickness)+"px";
+ s.position = "absolute";
+ s[control.vertical?"top":"left"] = "4px";
+ s.zIndex = 3;
+ setStyles(control.paneslider, scc.TCpanesliderStyle);
+ s.backgroundImage="url("+imageprefix+"paneslider-"+vh+".gif)";
+ if (scc.TCpanesliderClass) control.paneslider.className = scc.TCpanesliderClass;
+ AssignID(control.editor, control.paneslider, "paneslider"+vh);
+ TooltipRegister(control.paneslider, "paneslider", vh);
+
+ functions = {MouseDown:SocialCalc.TCPSDragFunctionStart,
+ MouseMove: SocialCalc.TCPSDragFunctionMove,
+ MouseUp: SocialCalc.TCPSDragFunctionStop,
+ Disabled: function() {return control.editor.busy;}};
+
+ functions.control = control; // make sure this is there
+
+ SocialCalc.DragRegister(control.paneslider, control.vertical, !control.vertical, functions);
+
+ control.main.appendChild(control.paneslider);
+
+ control.lessbutton = document.createElement("div");
+ s = control.lessbutton.style;
+ s.height = (control.vertical ? control.buttonthickness : control.controlthickness)+"px";
+ s.width = (control.vertical ? control.controlthickness : control.buttonthickness)+"px";
+ s.zIndex = 2;
+ s.overflow = "hidden"; // IE will make the DIV at least font-size height...so use this
+ s.position = "absolute";
+ setStyles(control.lessbutton, scc.TClessbuttonStyle);
+ s.backgroundImage="url("+imageprefix+"less-"+vh+"n.gif)"
+ if (scc.TClessbuttonClass) control.lessbutton.className = scc.TClessbuttonClass;
+ AssignID(control.editor, control.lessbutton, "lessbutton"+vh);
+
+ params = {repeatwait:scc.TClessbuttonRepeatWait, repeatinterval:scc.TClessbuttonRepeatInterval,
+ normalstyle: "backgroundImage:url("+imageprefix+"less-"+vh+"n.gif);",
+ downstyle: "backgroundImage:url("+imageprefix+"less-"+vh+"d.gif);",
+ hoverstyle: "backgroundImage:url("+imageprefix+"less-"+vh+"h.gif);"};
+ functions = {MouseDown:function(){if(!control.editor.busy) control.editor.ScrollRelative(control.vertical, -1);},
+ Repeat:function(){if(!control.editor.busy) control.editor.ScrollRelative(control.vertical, -1);},
+ Disabled: function() {return control.editor.busy;}};
+
+ SocialCalc.ButtonRegister(control.lessbutton, params, functions);
+
+ control.main.appendChild(control.lessbutton);
+
+ control.morebutton = document.createElement("div");
+ s = control.morebutton.style;
+ s.height = (control.vertical ? control.buttonthickness : control.controlthickness)+"px";
+ s.width = (control.vertical ? control.controlthickness : control.buttonthickness)+"px";
+ s.zIndex = 2;
+ s.overflow = "hidden"; // IE will make the DIV at least font-size height...so use this
+ s.position = "absolute";
+ setStyles(control.morebutton, scc.TCmorebuttonStyle);
+ s.backgroundImage="url("+imageprefix+"more-"+vh+"n.gif)"
+ if (scc.TCmorebuttonClass) control.morebutton.className = scc.TCmorebuttonClass;
+ AssignID(control.editor, control.morebutton, "morebutton"+vh);
+
+ params = {repeatwait:scc.TCmorebuttonRepeatWait, repeatinterval:scc.TCmorebuttonRepeatInterval,
+ normalstyle: "backgroundImage:url("+imageprefix+"more-"+vh+"n.gif);",
+ downstyle: "backgroundImage:url("+imageprefix+"more-"+vh+"d.gif);",
+ hoverstyle: "backgroundImage:url("+imageprefix+"more-"+vh+"h.gif);"};
+ functions = {MouseDown:function(){if(!control.editor.busy) control.editor.ScrollRelative(control.vertical, +1);},
+ Repeat:function(){if(!control.editor.busy) control.editor.ScrollRelative(control.vertical, +1);},
+ Disabled: function() {return control.editor.busy;}};
+
+ SocialCalc.ButtonRegister(control.morebutton, params, functions);
+
+ control.main.appendChild(control.morebutton);
+
+ control.scrollarea = document.createElement("div");
+ s = control.scrollarea.style;
+ s.height = control.controlthickness+"px";
+ s.width = control.controlthickness+"px";
+ s.zIndex = 1;
+ s.overflow = "hidden"; // IE will make the DIV at least font-size height...so use this
+ s.position = "absolute";
+ setStyles(control.scrollarea, scc.TCscrollareaStyle);
+ s.backgroundImage="url("+imageprefix+"scrollarea-"+vh+".gif)";
+ if (scc.TCscrollareaClass) control.scrollarea.className = scc.TCscrollareaClass;
+ AssignID(control.editor, control.scrollarea, "scrollarea"+vh);
+
+ params = {repeatwait:scc.TCscrollareaRepeatWait, repeatinterval:scc.TCscrollareaRepeatWait};
+ functions = {MouseDown:SocialCalc.ScrollAreaClick, Repeat:SocialCalc.ScrollAreaClick,
+ Disabled: function() {return control.editor.busy;}};
+ functions.control = control;
+
+ SocialCalc.ButtonRegister(control.scrollarea, params, functions);
+
+ control.main.appendChild(control.scrollarea);
+
+ control.thumb = document.createElement("div");
+ s = control.thumb.style;
+ s.height = (control.vertical ? control.thumbthickness : control.controlthickness)+"px";
+ s.width = (control.vertical ? control.controlthickness : control.thumbthickness)+"px";
+ s.zIndex = 2;
+ s.overflow = "hidden"; // IE will make the DIV at least font-size height...so use this
+ s.position = "absolute";
+ setStyles(control.thumb, scc.TCthumbStyle);
+ control.thumb.style.backgroundImage="url("+imageprefix+"thumb-"+vh+"n.gif)";
+ if (scc.TCthumbClass) control.thumb.className = scc.TCthumbClass;
+ AssignID(control.editor, control.thumb, "thumb"+vh);
+
+ functions = {MouseDown:SocialCalc.TCTDragFunctionStart,
+ MouseMove: SocialCalc.TCTDragFunctionMove,
+ MouseUp: SocialCalc.TCTDragFunctionStop,
+ Disabled: function() {return control.editor.busy;}};
+ functions.control = control; // make sure this is there
+ SocialCalc.DragRegister(control.thumb, control.vertical, !control.vertical, functions);
+
+ params = {normalstyle: "backgroundImage:url("+imageprefix+"thumb-"+vh+"n.gif)", name:"Thumb",
+ downstyle: "backgroundImage:url("+imageprefix+"thumb-"+vh+"d.gif)",
+ hoverstyle: "backgroundImage:url("+imageprefix+"thumb-"+vh+"h.gif)"};
+ SocialCalc.ButtonRegister(control.thumb, params, null); // give it button-like visual behavior
+
+ control.main.appendChild(control.thumb);
+
+ return control.main;
+
+}
+
+//
+// ScrollAreaClick - Button function to process pageup/down clicks
+//
+
+SocialCalc.ScrollAreaClick = function(e, buttoninfo, bobj) {
+
+ var control = bobj.functionobj.control;
+ var bposition = SocialCalc.GetElementPosition(bobj.element);
+ var clickpos = control.vertical ? buttoninfo.clientY : buttoninfo.clientX;
+ if (control.editor.busy) { // ignore if busy - wait for next repeat
+ return;
+ }
+ control.editor.PageRelative(control.vertical, clickpos > control.thumbpos ? 1 : -1);
+
+ return;
+
+}
+
+//
+// PositionTableControlElements
+//
+
+SocialCalc.PositionTableControlElements = function(control) {
+
+ var border, realend, thumbpos;
+
+ var editor = control.editor;
+
+ if (control.vertical) {
+ border = control.controlborder+"px";
+ control.endcap.style.top = control.endcapstart+"px";
+ control.endcap.style.left = border;
+ control.paneslider.style.top = control.panesliderstart+"px";
+ control.paneslider.style.left = border
+ control.lessbutton.style.top = control.lessbuttonstart+"px";
+ control.lessbutton.style.left = border;
+ control.morebutton.style.top = control.morebuttonstart+"px";
+ control.morebutton.style.left = border;
+ control.scrollarea.style.top = control.scrollareastart+"px";
+ control.scrollarea.style.left = border;
+ control.scrollarea.style.height = control.scrollareasize+"px";
+ realend = Math.max(editor.context.sheetobj.attribs.lastrow, editor.firstscrollingrow+1);
+ thumbpos = ((editor.firstscrollingrow-(editor.lastnonscrollingrow+1))*(control.scrollareasize-3*control.thumbthickness))/
+ (realend-(editor.lastnonscrollingrow+1))+control.scrollareastart-1;
+ thumbpos = Math.floor(thumbpos);
+ control.thumb.style.top = thumbpos+"px";
+ control.thumb.style.left = border;
+ }
+ else {
+ border = control.controlborder+"px";
+ control.endcap.style.left = control.endcapstart+"px";
+ control.endcap.style.top = border;
+ control.paneslider.style.left = control.panesliderstart+"px";
+ control.paneslider.style.top = border
+ control.lessbutton.style.left = control.lessbuttonstart+"px";
+ control.lessbutton.style.top = border;
+ control.morebutton.style.left = control.morebuttonstart+"px";
+ control.morebutton.style.top = border;
+ control.scrollarea.style.left = control.scrollareastart+"px";
+ control.scrollarea.style.top = border;
+ control.scrollarea.style.width = control.scrollareasize+"px";
+ realend = Math.max(editor.context.sheetobj.attribs.lastcol, editor.firstscrollingcol+1);
+ thumbpos = ((editor.firstscrollingcol-(editor.lastnonscrollingcol+1))*(control.scrollareasize-control.thumbthickness))/
+ (realend-editor.lastnonscrollingcol)+control.scrollareastart-1;
+ thumbpos = Math.floor(thumbpos);
+ control.thumb.style.left = thumbpos+"px";
+ control.thumb.style.top = border;
+ }
+ control.thumbpos = thumbpos;
+ control.main.style.display="block";
+
+ }
+
+//
+// ComputeTableControlPositions
+//
+// This routine computes the screen positions and other values needed for laying out
+// the table control elements.
+//
+
+SocialCalc.ComputeTableControlPositions = function(control) {
+
+ var editor = control.editor;
+
+ if (!editor.gridposition || !editor.headposition) throw("Can't compute table control positions before editor positions");
+
+ if (control.vertical) {
+ control.controlborder = editor.gridposition.left+editor.tablewidth; // border=left position
+ control.endcapstart = editor.gridposition.top; // start=top position
+ control.panesliderstart = editor.firstscrollingrowtop-control.sliderthickness;
+ control.lessbuttonstart = editor.firstscrollingrowtop-1;
+ control.morebuttonstart = editor.gridposition.top+editor.tableheight-control.buttonthickness;
+ control.scrollareastart = editor.firstscrollingrowtop-1+control.buttonthickness;
+ control.scrollareaend = control.morebuttonstart-1;
+ control.scrollareasize = control.scrollareaend-control.scrollareastart+1;
+ }
+ else {
+ control.controlborder = editor.gridposition.top+editor.tableheight; // border=top position
+ control.endcapstart = editor.gridposition.left; // start=left position
+ control.panesliderstart = editor.firstscrollingcolleft-control.sliderthickness;
+ control.lessbuttonstart = editor.firstscrollingcolleft-1;
+ control.morebuttonstart = editor.gridposition.left+editor.tablewidth-control.buttonthickness;
+ control.scrollareastart = editor.firstscrollingcolleft-1+control.buttonthickness;
+ control.scrollareaend = control.morebuttonstart-1;
+ control.scrollareasize = control.scrollareaend-control.scrollareastart+1;
+ }
+ }
+
+////// TCPS - TableControl Pan Slider methods
+
+//
+// TCPSDragFunctionStart(event, draginfo, dobj)
+//
+// TableControlPaneSlider function for starting drag
+//
+
+SocialCalc.TCPSDragFunctionStart = function(event, draginfo, dobj) {
+
+ var editor = dobj.functionobj.control.editor;
+ var scc = SocialCalc.Constants;
+
+ SocialCalc.DragFunctionStart(event, draginfo, dobj);
+
+ draginfo.trackingline = document.createElement("div");
+ draginfo.trackingline.style.height = dobj.vertical ? scc.TCPStrackinglineThickness :
+ (editor.tableheight-(editor.headposition.top-editor.gridposition.top))+"px";
+ draginfo.trackingline.style.width = dobj.vertical ?
+ (editor.tablewidth-(editor.headposition.left-editor.gridposition.left))+"px" : scc.TCPStrackinglineThickness;
+ draginfo.trackingline.style.backgroundImage="url("+editor.imageprefix+"trackingline-"+(dobj.vertical?"v":"h")+".gif)";;
+ if (scc.TCPStrackinglineClass) draginfo.trackingline.className = scc.TCPStrackinglineClass;
+ SocialCalc.setStyles(draginfo.trackingline, scc.TCPStrackinglineStyle);
+
+ if (dobj.vertical) {
+ row = SocialCalc.Lookup(draginfo.clientY+dobj.functionobj.control.sliderthickness, editor.rowpositions);
+ draginfo.trackingline.style.top = (editor.rowpositions[row] || editor.headposition.top)+"px";
+ draginfo.trackingline.style.left = editor.headposition.left+"px";
+ if (editor.context.rowpanes.length-1) { // has 2 already
+ editor.context.SetRowPaneFirstLast(1, editor.context.rowpanes[0].last+1, editor.context.rowpanes[0].last+1);
+ editor.FitToEditTable();
+ editor.ScheduleRender();
+ }
+ }
+ else {
+ col = SocialCalc.Lookup(draginfo.clientX+dobj.functionobj.control.sliderthickness, editor.colpositions);
+ draginfo.trackingline.style.top = editor.headposition.top+"px";
+ draginfo.trackingline.style.left = (editor.colpositions[col] || editor.headposition.left)+"px";
+ if (editor.context.colpanes.length-1) { // has 2 already
+ editor.context.SetColPaneFirstLast(1, editor.context.colpanes[0].last+1, editor.context.colpanes[0].last+1);
+ editor.FitToEditTable();
+ editor.ScheduleRender();
+ }
+ }
+
+ editor.griddiv.appendChild(draginfo.trackingline);
+
+ }
+
+//
+// TCPSDragFunctionMove(event, draginfo, dobj)
+//
+
+SocialCalc.TCPSDragFunctionMove = function(event, draginfo, dobj) {
+
+ var row, col, max, min;
+ var control = dobj.functionobj.control;
+ var sliderthickness = control.sliderthickness;
+ var editor = control.editor;
+
+ if (dobj.vertical) {
+ max = control.morebuttonstart - control.minscrollingpanesize - draginfo.offsetY; // restrict movement
+ if (draginfo.clientY > max) draginfo.clientY = max;
+ min = editor.headposition.top - sliderthickness - draginfo.offsetY;
+ if (draginfo.clientY < min) draginfo.clientY = min;
+
+ row = SocialCalc.Lookup(draginfo.clientY+sliderthickness, editor.rowpositions);
+ draginfo.trackingline.style.top = (editor.rowpositions[row] || editor.headposition.top)+"px";
+ }
+ else {
+ max = control.morebuttonstart - control.minscrollingpanesize - draginfo.offsetX;
+ if (draginfo.clientX > max) draginfo.clientX = max;
+ min = editor.headposition.left - sliderthickness - draginfo.offsetX;
+ if (draginfo.clientX < min) draginfo.clientX = min;
+
+ col = SocialCalc.Lookup(draginfo.clientX+sliderthickness, editor.colpositions);
+ draginfo.trackingline.style.left = (editor.colpositions[col] || editor.headposition.left)+"px";
+ }
+
+ SocialCalc.DragFunctionPosition(event, draginfo, dobj);
+
+ }
+
+//
+// TCPSDragFunctionStop(event, draginfo, dobj)
+//
+
+SocialCalc.TCPSDragFunctionStop = function(event, draginfo, dobj) {
+
+ var row, col, max, min;
+ var control = dobj.functionobj.control;
+ var sliderthickness = control.sliderthickness;
+ var editor = control.editor;
+
+ if (dobj.vertical) {
+ max = control.morebuttonstart - control.minscrollingpanesize - draginfo.offsetY; // restrict movement
+ if (draginfo.clientY > max) draginfo.clientY = max;
+ min = editor.headposition.top - sliderthickness - draginfo.offsetY;
+ if (draginfo.clientY < min) draginfo.clientY = min;
+
+ row = SocialCalc.Lookup(draginfo.clientY+sliderthickness, editor.rowpositions);
+ if (row>editor.context.sheetobj.attribs.lastrow) row=editor.context.sheetobj.attribs.lastrow; // can't extend sheet here
+ if (!row || row<=editor.context.rowpanes[0].first) { // set to no panes, leaving first pane settings
+ if (editor.context.rowpanes.length>1) editor.context.rowpanes.length = 1;
+ }
+ else if (editor.context.rowpanes.length-1) { // has 2 already
+ if (!editor.timeout) { // not waiting for position calc (so positions could be wrong)
+ editor.context.SetRowPaneFirstLast(0, editor.context.rowpanes[0].first, row-1);
+ editor.context.SetRowPaneFirstLast(1, row, row);
+ }
+ }
+ else {
+ editor.context.SetRowPaneFirstLast(0, editor.context.rowpanes[0].first, row-1);
+ editor.context.SetRowPaneFirstLast(1, row, row);
+ }
+ }
+ else {
+ max = control.morebuttonstart - control.minscrollingpanesize - draginfo.offsetX;
+ if (draginfo.clientX > max) draginfo.clientX = max;
+ min = editor.headposition.left - sliderthickness - draginfo.offsetX;
+ if (draginfo.clientX < min) draginfo.clientX = min;
+
+ col = SocialCalc.Lookup(draginfo.clientX+sliderthickness, editor.colpositions);
+ if (col>editor.context.sheetobj.attribs.lastcol) col=editor.context.sheetobj.attribs.lastcol; // can't extend sheet here
+ if (!col || col<=editor.context.colpanes[0].first) { // set to no panes, leaving first pane settings
+ if (editor.context.colpanes.length>1) editor.context.colpanes.length = 1;
+ }
+ else if (editor.context.colpanes.length-1) { // has 2 already
+ if (!editor.timeout) { // not waiting for position calc (so positions could be wrong)
+ editor.context.SetColPaneFirstLast(0, editor.context.colpanes[0].first, col-1);
+ editor.context.SetColPaneFirstLast(1, col, col);
+ }
+ }
+ else {
+ editor.context.SetColPaneFirstLast(0, editor.context.colpanes[0].first, col-1);
+ editor.context.SetColPaneFirstLast(1, col, col);
+ }
+ }
+
+ editor.FitToEditTable();
+
+ editor.griddiv.removeChild(draginfo.trackingline);
+
+ editor.ScheduleRender();
+
+ }
+
+////// TCT - TableControl Thumb methods
+
+//!!!! Note: Need to make start use same code as move/stop for determining row/col, since stop will set that
+//!!!! Note: Need to make start/move/stop use positioning code that corresponds closer to
+//!!!! ComputeTableControlPositions calculations.
+
+//
+// TCTDragFunctionStart(event, draginfo, dobj)
+//
+// TableControlThumb function for starting drag
+//
+
+SocialCalc.TCTDragFunctionStart = function(event, draginfo, dobj) {
+
+ var rowpane, colpane, row, col;
+
+ var control = dobj.functionobj.control;
+ var editor = control.editor;
+ var scc = SocialCalc.Constants;
+
+ SocialCalc.DragFunctionStart(event, draginfo, dobj);
+
+ draginfo.thumbstatus = document.createElement("div");
+
+ if (dobj.vertical) {
+ if (scc.TCTDFSthumbstatusvClass) draginfo.thumbstatus.className = scc.TCTDFSthumbstatusvClass;
+ SocialCalc.setStyles(draginfo.thumbstatus, scc.TCTDFSthumbstatusvStyle);
+ draginfo.thumbstatus.style.top = (draginfo.clientY+scc.TCTDFStopOffsetv)+"px";
+ draginfo.thumbstatus.style.left = (control.controlborder-10-(editor.tablewidth/2))+"px";
+ draginfo.thumbstatus.style.width = (editor.tablewidth/2)+"px";
+
+ draginfo.thumbcontext = new SocialCalc.RenderContext(editor.context.sheetobj);
+ draginfo.thumbcontext.showGrid = true;
+ draginfo.thumbcontext.rowpanes = [{first: 1, last: 1}];
+ var pane = editor.context.colpanes[editor.context.colpanes.length-1];
+ draginfo.thumbcontext.colpanes = [{first: pane.first, last: pane.last}];
+ draginfo.thumbstatus.innerHTML = '<table cellspacing="0" cellpadding="0"><tr><td valign="top" style="'+
+ scc.TCTDFSthumbstatusrownumStyle+'" class="'+scc.TCTDFSthumbstatusrownumClass+
+ '"><div>msg</div></td><td valign="top"><div style="overflow:hidden;">preview</div></td></tr></table>';
+ draginfo.thumbstatus.rowmsgele = draginfo.thumbstatus.firstChild.firstChild.firstChild.firstChild.firstChild;
+ draginfo.thumbstatus.rowpreviewele = draginfo.thumbstatus.firstChild.firstChild.firstChild.childNodes[1].firstChild;
+ editor.toplevel.appendChild(draginfo.thumbstatus);
+ SocialCalc.TCTDragFunctionRowSetStatus(draginfo, editor, editor.firstscrollingrow || 1);
+ }
+ else {
+ if (scc.TCTDFSthumbstatushClass) draginfo.thumbstatus.className = scc.TCTDFSthumbstatushClass;
+ SocialCalc.setStyles(draginfo.thumbstatus, scc.TCTDFSthumbstatushStyle);
+ draginfo.thumbstatus.style.top = (control.controlborder+scc.TCTDFStopOffseth)+"px";
+ draginfo.thumbstatus.style.left = (draginfo.clientX+scc.TCTDFSleftOffseth)+"px";
+ editor.toplevel.appendChild(draginfo.thumbstatus);
+ draginfo.thumbstatus.innerHTML = scc.s_TCTDFthumbstatusPrefixh+SocialCalc.rcColname(editor.firstscrollingcol);
+ }
+
+ }
+
+
+//
+// SocialCalc.TCTDragFunctionRowSetStatus(draginfo, editor, row)
+//
+// Render partial row
+//
+
+SocialCalc.TCTDragFunctionRowSetStatus = function(draginfo, editor, row) {
+
+ var scc = SocialCalc.Constants;
+ var msg = scc.s_TCTDFthumbstatusPrefixv+row+" ";
+
+ draginfo.thumbstatus.rowmsgele.innerHTML = msg;
+
+ draginfo.thumbcontext.rowpanes = [{first: row, last: row}];
+ draginfo.thumbrowshown = row;
+
+ var ele = draginfo.thumbcontext.RenderSheet(draginfo.thumbstatus.rowpreviewele.firstChild, {type: "html"});
+
+ }
+
+
+//
+// TCTDragFunctionMove(event, draginfo, dobj)
+//
+
+SocialCalc.TCTDragFunctionMove = function(event, draginfo, dobj) {
+
+ var first, msg;
+ var control = dobj.functionobj.control;
+ var thumbthickness = control.thumbthickness;
+ var editor = control.editor;
+ var scc = SocialCalc.Constants;
+
+ if (dobj.vertical) {
+ if (draginfo.clientY > control.scrollareaend - draginfo.offsetY - control.thumbthickness + 2)
+ draginfo.clientY = control.scrollareaend - draginfo.offsetY - control.thumbthickness + 2;
+ if (draginfo.clientY < control.scrollareastart - draginfo.offsetY - 1)
+ draginfo.clientY = control.scrollareastart - draginfo.offsetY - 1;
+ draginfo.thumbstatus.style.top = draginfo.clientY+"px";
+
+ first =
+ ((draginfo.clientY+draginfo.offsetY-control.scrollareastart+1)/(control.scrollareasize-control.thumbthickness))
+ * (editor.context.sheetobj.attribs.lastrow-editor.lastnonscrollingrow)
+ + editor.lastnonscrollingrow + 1;
+ first = Math.floor(first);
+ if (first <= editor.lastnonscrollingrow) first = editor.lastnonscrollingrow + 1;
+ if (first > editor.context.sheetobj.attribs.lastrow) first = editor.context.sheetobj.attribs.lastrow;
+// msg = scc.s_TCTDFthumbstatusPrefixv+first;
+ if (first != draginfo.thumbrowshown) {
+ SocialCalc.TCTDragFunctionRowSetStatus(draginfo, editor, first);
+ }
+ }
+ else {
+ if (draginfo.clientX > control.scrollareaend - draginfo.offsetX - control.thumbthickness + 2)
+ draginfo.clientX = control.scrollareaend - draginfo.offsetX - control.thumbthickness + 2;
+ if (draginfo.clientX < control.scrollareastart - draginfo.offsetX - 1)
+ draginfo.clientX = control.scrollareastart - draginfo.offsetX - 1;
+ draginfo.thumbstatus.style.left = draginfo.clientX+"px";
+
+ first =
+ ((draginfo.clientX+draginfo.offsetX-control.scrollareastart+1)/(control.scrollareasize-control.thumbthickness))
+ * (editor.context.sheetobj.attribs.lastcol-editor.lastnonscrollingcol)
+ + editor.lastnonscrollingcol + 1;
+ first = Math.floor(first);
+ if (first <= editor.lastnonscrollingcol) first = editor.lastnonscrollingcol + 1;
+ if (first > editor.context.sheetobj.attribs.lastcol) first = editor.context.sheetobj.attribs.lastcol;
+ msg = scc.s_TCTDFthumbstatusPrefixh+SocialCalc.rcColname(first);
+ draginfo.thumbstatus.innerHTML = msg;
+ }
+
+ SocialCalc.DragFunctionPosition(event, draginfo, dobj);
+
+ }
+
+//
+// TCTDragFunctionStop(event, draginfo, dobj)
+//
+
+SocialCalc.TCTDragFunctionStop = function(event, draginfo, dobj) {
+
+ var first;
+ var control = dobj.functionobj.control;
+ var editor = control.editor;
+
+ if (dobj.vertical) {
+ first =
+ ((draginfo.clientY+draginfo.offsetY-control.scrollareastart+1)/(control.scrollareasize-control.thumbthickness))
+ * (editor.context.sheetobj.attribs.lastrow-editor.lastnonscrollingrow)
+ + editor.lastnonscrollingrow + 1;
+ first = Math.floor(first);
+ if (first <= editor.lastnonscrollingrow) first = editor.lastnonscrollingrow + 1;
+ if (first > editor.context.sheetobj.attribs.lastrow) first = editor.context.sheetobj.attribs.lastrow;
+
+ editor.context.SetRowPaneFirstLast(editor.context.rowpanes.length-1, first, first+1);
+ }
+ else {
+ first =
+ ((draginfo.clientX+draginfo.offsetX-control.scrollareastart+1)/(control.scrollareasize-control.thumbthickness))
+ * (editor.context.sheetobj.attribs.lastcol-editor.lastnonscrollingcol)
+ + editor.lastnonscrollingcol + 1;
+ first = Math.floor(first);
+ if (first <= editor.lastnonscrollingcol) first = editor.lastnonscrollingcol + 1;
+ if (first > editor.context.sheetobj.attribs.lastcol) first = editor.context.sheetobj.attribs.lastcol;
+
+ editor.context.SetColPaneFirstLast(editor.context.colpanes.length-1, first, first+1);
+ }
+
+ editor.FitToEditTable();
+
+ draginfo.thumbstatus.rowmsgele = null;
+ draginfo.thumbstatus.rowpreviewele = null;
+ editor.toplevel.removeChild(draginfo.thumbstatus);
+ draginfo.thumbstatus = null;
+
+ editor.ScheduleRender();
+
+ }
+
+// *************************************
+//
+// Dragging functions:
+//
+// *************************************
+
+SocialCalc.DragInfo = {
+
+ // There is only one of these -- no "new" is done.
+ // Only one dragging operation can be active at a time.
+ // The registeredElements array is used to decide which item to drag.
+
+ // One item for each draggable thing, each an object with:
+ // .element, .vertical, .horizontal, .functionobj
+
+ registeredElements: [],
+
+ // Items used during a drag
+
+ draggingElement: null, // item being processed (.element is the actual element)
+ startX: 0,
+ startY: 0,
+ startZ: 0,
+ clientX: 0, // modifyable version to restrict movement
+ clientY: 0,
+ offsetX: 0,
+ offsetY: 0,
+ horizontalScroll: 0, // retrieved at drag start
+ verticalScroll: 0
+
+ }
+
+//
+// DragRegister(element, vertical, horizontal, functionobj) - make element draggable
+//
+// The functionobj defaults to moving the element contrained only by vertical and horizontal settings.
+//
+
+SocialCalc.DragRegister = function(element, vertical, horizontal, functionobj) {
+
+ var draginfo = SocialCalc.DragInfo;
+
+ if (!functionobj) {
+ functionobj = {MouseDown: SocialCalc.DragFunctionStart, MouseMove: SocialCalc.DragFunctionPosition,
+ MouseUp: SocialCalc.DragFunctionPosition,
+ Disabled: null};
+ }
+
+ draginfo.registeredElements.push(
+ {element: element, vertical: vertical, horizontal: horizontal, functionobj: functionobj}
+ );
+
+ if (element.addEventListener) { // DOM Level 2 -- Firefox, et al
+ element.addEventListener("mousedown", SocialCalc.DragMouseDown, false);
+ }
+ else if (element.attachEvent) { // IE 5+
+ element.attachEvent("onmousedown", SocialCalc.DragMouseDown);
+ }
+ else { // don't handle this
+ throw SocialCalc.Constants.s_BrowserNotSupported;
+ }
+
+ }
+
+//
+// DragUnregister(element) - remove object from list
+//
+
+SocialCalc.DragUnregister = function(element) {
+
+ var draginfo = SocialCalc.DragInfo;
+
+ var i;
+
+ if (!element) return;
+
+ for (i=0; i<draginfo.registeredElements.length; i++) {
+ if (draginfo.registeredElements[i].element == element) {
+ draginfo.registeredElements.splice(i,1);
+ if (element.removeEventListener) { // DOM Level 2 -- Firefox, et al
+ element.removeEventListener("mousedown", SocialCalc.DragMouseDown, false);
+ }
+ else { // IE 5+
+ element.detachEvent("onmousedown", SocialCalc.DragMouseDown);
+ }
+ return;
+ }
+ }
+
+ return; // ignore if not in list
+
+ }
+
+//
+// DragMouseDown(event)
+//
+
+SocialCalc.DragMouseDown = function(event) {
+
+ var e = event || window.event;
+
+ var draginfo = SocialCalc.DragInfo;
+
+ var dobj = SocialCalc.LookupElement(e.target || e.srcElement, draginfo.registeredElements);
+ if (!dobj) return;
+
+ if (dobj && dobj.functionobj && dobj.functionobj.Disabled) {
+ if (dobj.functionobj.Disabled(e, draginfo, dobj)) {
+ return;
+ }
+ }
+
+ draginfo.draggingElement = dobj;
+
+ var viewportinfo = SocialCalc.GetViewportInfo();
+ draginfo.horizontalScroll = viewportinfo.horizontalScroll;
+ draginfo.verticalScroll = viewportinfo.verticalScroll;
+
+ draginfo.clientX = e.clientX + draginfo.horizontalScroll; // get document-relative coordinates
+ draginfo.clientY = e.clientY + draginfo.verticalScroll;
+ draginfo.startX = draginfo.clientX;
+ draginfo.startY = draginfo.clientY;
+ draginfo.startZ = dobj.element.style.zIndex;
+ draginfo.offsetX = 0;
+ draginfo.offsetY = 0;
+
+ dobj.element.style.zIndex = "100";
+
+ // Event code from JavaScript, Flanagan, 5th Edition, pg. 422
+ if (document.addEventListener) { // DOM Level 2 -- Firefox, et al
+ document.addEventListener("mousemove", SocialCalc.DragMouseMove, true); // capture everywhere
+ document.addEventListener("mouseup", SocialCalc.DragMouseUp, true);
+ }
+ else if (dobj.element.attachEvent) { // IE 5+
+ dobj.element.setCapture();
+ dobj.element.attachEvent("onmousemove", SocialCalc.DragMouseMove);
+ dobj.element.attachEvent("onmouseup", SocialCalc.DragMouseUp);
+ dobj.element.attachEvent("onlosecapture", SocialCalc.DragMouseUp);
+ }
+ if (e.stopPropagation) e.stopPropagation(); // DOM Level 2
+ else e.cancelBubble = true; // IE 5+
+ if (e.preventDefault) e.preventDefault(); // DOM Level 2
+ else e.returnValue = false; // IE 5+
+
+ if (dobj && dobj.functionobj && dobj.functionobj.MouseDown) dobj.functionobj.MouseDown(e, draginfo, dobj);
+
+ return false;
+
+ }
+
+//
+// DragMouseMove(event)
+//
+
+SocialCalc.DragMouseMove = function(event) {
+
+ var e = event || window.event;
+
+ var draginfo = SocialCalc.DragInfo;
+ draginfo.clientX = e.clientX + draginfo.horizontalScroll;
+ draginfo.clientY = e.clientY + draginfo.verticalScroll;
+
+ var dobj = draginfo.draggingElement;
+
+ if (e.stopPropagation) e.stopPropagation(); // DOM Level 2
+ else e.cancelBubble = true; // IE 5+
+
+ if (dobj && dobj.functionobj && dobj.functionobj.MouseMove) dobj.functionobj.MouseMove(e, draginfo, dobj);
+
+ return false;
+
+ }
+
+//
+// DragMouseUp(event)
+//
+
+SocialCalc.DragMouseUp = function(event) {
+
+ var e = event || window.event;
+
+ var draginfo = SocialCalc.DragInfo;
+ draginfo.clientX = e.clientX + draginfo.horizontalScroll;
+ draginfo.clientY = e.clientY + draginfo.verticalScroll;
+
+ var dobj = draginfo.draggingElement;
+
+ dobj.element.style.zIndex = draginfo.startZ;
+
+ if (dobj && dobj.functionobj && dobj.functionobj.MouseUp) dobj.functionobj.MouseUp(e, draginfo, dobj);
+
+ if (e.stopPropagation) e.stopPropagation(); // DOM Level 2
+ else e.cancelBubble = true; // IE 5+
+
+ if (document.removeEventListener) { // DOM Level 2
+ document.removeEventListener("mousemove", SocialCalc.DragMouseMove, true);
+ document.removeEventListener("mouseup", SocialCalc.DragMouseUp, true);
+ // Note: In old (1.5?) versions of Firefox, this causes the browser to skip the MouseUp for
+ // the button code. https://bugzilla.mozilla.org/show_bug.cgi?id=174320
+ // Firefox 1.5 is <1% share (http://marketshare.hitslink.com/report.aspx?qprid=7)
+ }
+ else if (dobj.element.detachEvent) { // IE
+ dobj.element.detachEvent("onlosecapture", SocialCalc.DragMouseUp);
+ dobj.element.detachEvent("onmouseup", SocialCalc.DragMouseUp);
+ dobj.element.detachEvent("onmousemove", SocialCalc.DragMouseMove);
+ dobj.element.releaseCapture();
+ }
+
+ draginfo.draggingElement = null;
+
+ return false;
+
+ }
+
+//
+// DragFunctionStart(event, draginfo, dobj)
+//
+
+SocialCalc.DragFunctionStart = function(event, draginfo, dobj) {
+
+ var val;
+ var element = dobj.functionobj.positionobj || dobj.element;
+
+ val = element.style.top.match(/\d*/);
+ draginfo.offsetY = (val ? val[0]-0 : 0) - draginfo.clientY;
+ val = element.style.left.match(/\d*/);
+ draginfo.offsetX = (val ? val[0]-0 : 0) - draginfo.clientX;
+
+ }
+
+//
+// DragFunctionPosition(event, draginfo, dobj)
+//
+
+SocialCalc.DragFunctionPosition = function(event, draginfo, dobj) {
+
+ var element = dobj.functionobj.positionobj || dobj.element;
+
+ if (dobj.vertical) element.style.top = (draginfo.clientY + draginfo.offsetY)+"px";
+ if (dobj.horizontal) element.style.left = (draginfo.clientX + draginfo.offsetX)+"px";
+
+ }
+
+// *************************************
+//
+// Tooltip functions:
+//
+// *************************************
+
+SocialCalc.TooltipInfo = {
+
+ // There is only one of these -- no "new" is done.
+ // Only one tooltip operation can be active at a time.
+ // The registeredElements array is used to identify items.
+
+ // One item for each element with a tooltip, each an object with:
+ // .element, .tiptext, .functionobj
+ // Currently .functionobj can only contain .offsetx and .offsety.
+ // If present they are used instead of the default ones.
+
+ registeredElements: [],
+
+ registered: false, // if true, an event handler has been registered for this functionality
+
+ // Items used during hover over an element
+
+ tooltipElement: null, // item being processed (.element is the actual element)
+ timer: null, // timer object waiting to see if holding over element
+ popupElement: null, // tooltip element being displayed
+ clientX: 0, // modifyable version to restrict movement
+ clientY: 0,
+ offsetX: SocialCalc.Constants.TooltipOffsetX, // modifyable version to allow positioning
+ offsetY: SocialCalc.Constants.TooltipOffsetY
+
+ }
+
+//
+// TooltipRegister(element, tiptext, functionobj) - make element have a tooltip
+//
+
+SocialCalc.TooltipRegister = function(element, tiptext, functionobj) {
+
+ var tooltipinfo = SocialCalc.TooltipInfo;
+ tooltipinfo.registeredElements.push(
+ {element: element, tiptext: tiptext, functionobj: functionobj}
+ );
+
+ if (tooltipinfo.registered) return; // only need to add event listener once
+
+ if (document.addEventListener) { // DOM Level 2 -- Firefox, et al
+ document.addEventListener("mousemove", SocialCalc.TooltipMouseMove, false);
+ }
+ else if (document.attachEvent) { // IE 5+
+ document.attachEvent("onmousemove", SocialCalc.TooltipMouseMove);
+ }
+ else { // don't handle this
+ throw SocialCalc.Constants.s_BrowserNotSupported;
+ }
+
+ tooltipinfo.registered = true; // remember
+
+ return;
+
+ }
+
+//
+// TooltipMouseMove(event)
+//
+
+SocialCalc.TooltipMouseMove = function(event) {
+
+ var e = event || window.event;
+
+ var tooltipinfo = SocialCalc.TooltipInfo;
+
+ tooltipinfo.viewport = SocialCalc.GetViewportInfo();
+ tooltipinfo.clientX = e.clientX + tooltipinfo.viewport.horizontalScroll;
+ tooltipinfo.clientY = e.clientY + tooltipinfo.viewport.verticalScroll;
+
+ var tobj = SocialCalc.LookupElement(e.target || e.srcElement, tooltipinfo.registeredElements);
+
+ if (tooltipinfo.timer) { // waiting to see if holding still: didn't hold still
+ window.clearTimeout(tooltipinfo.timer); // cancel timer
+ tooltipinfo.timer = null;
+ }
+
+ if (tooltipinfo.popupElement) { // currently displaying a tip: hide it
+ SocialCalc.TooltipHide();
+ }
+
+ tooltipinfo.tooltipElement = tobj || null;
+
+ if (!tobj || SocialCalc.ButtonInfo.buttonDown) return; // if not an object with a tip or a "button" is down, ignore
+
+ tooltipinfo.timer = window.setTimeout(SocialCalc.TooltipWaitDone, 700);
+
+ if (tooltipinfo.tooltipElement.element.addEventListener) { // Register event for mouse down which cancels tooltip stuff
+ tooltipinfo.tooltipElement.element.addEventListener("mousedown", SocialCalc.TooltipMouseDown, false);
+ }
+ else if (tooltipinfo.tooltipElement.element.attachEvent) { // IE
+ tooltipinfo.tooltipElement.element.attachEvent("onmousedown", SocialCalc.TooltipMouseDown);
+ }
+
+ return;
+
+ }
+
+//
+// TooltipMouseDown(event)
+//
+
+SocialCalc.TooltipMouseDown = function(event) {
+
+ var e = event || window.event;
+
+ var tooltipinfo = SocialCalc.TooltipInfo;
+
+ if (tooltipinfo.timer) {
+ window.clearTimeout(tooltipinfo.timer); // cancel timer
+ tooltipinfo.timer = null;
+ }
+
+ if (tooltipinfo.popupElement) { // currently displaying a tip: hide it
+ SocialCalc.TooltipHide();
+ }
+
+ if (tooltipinfo.tooltipElement) {
+ if (tooltipinfo.tooltipElement.element.removeEventListener) { // DOM Level 2 -- Firefox, et al
+ tooltipinfo.tooltipElement.element.removeEventListener("mousedown", SocialCalc.TooltipMouseDown, false);
+ }
+ else if (tooltipinfo.tooltipElement.element.attachEvent) { // IE 5+
+ tooltipinfo.tooltipElement.element.detachEvent("onmousedown", SocialCalc.TooltipMouseDown);
+ }
+ tooltipinfo.tooltipElement = null;
+ }
+
+ return;
+
+ }
+
+//
+// TooltipDisplay(tobj)
+//
+
+SocialCalc.TooltipDisplay = function(tobj) {
+
+ var tooltipinfo = SocialCalc.TooltipInfo;
+ var scc = SocialCalc.Constants;
+ var offsetX = (tobj.functionobj && ((typeof tobj.functionobj.offsetx) == "number")) ? tobj.functionobj.offsetx : tooltipinfo.offsetX;
+ var offsetY = (tobj.functionobj && ((typeof tobj.functionobj.offsety) == "number")) ? tobj.functionobj.offsety : tooltipinfo.offsetY;
+
+ tooltipinfo.popupElement = document.createElement("div");
+ if (scc.TDpopupElementClass) tooltipinfo.popupElement.className = scc.TDpopupElementClass;
+ SocialCalc.setStyles(tooltipinfo.popupElement, scc.TDpopupElementStyle);
+
+ tooltipinfo.popupElement.innerHTML = tobj.tiptext;
+
+ if (tooltipinfo.clientX > tooltipinfo.viewport.width/2) { // on right side of screen
+ tooltipinfo.popupElement.style.bottom = (tooltipinfo.viewport.height - tooltipinfo.clientY + offsetY)+"px";
+ tooltipinfo.popupElement.style.right = (tooltipinfo.viewport.width - tooltipinfo.clientX + offsetX)+"px";
+ }
+ else { // on left side of screen
+ tooltipinfo.popupElement.style.bottom = (tooltipinfo.viewport.height - tooltipinfo.clientY + offsetY)+"px";
+ tooltipinfo.popupElement.style.left = (tooltipinfo.clientX + offsetX)+"px";
+ }
+
+ document.body.appendChild(tooltipinfo.popupElement);
+
+ }
+
+//
+// TooltipHide()
+//
+
+SocialCalc.TooltipHide = function() {
+
+ var tooltipinfo = SocialCalc.TooltipInfo;
+
+ if (tooltipinfo.popupElement) {
+ tooltipinfo.popupElement.parentNode.removeChild(tooltipinfo.popupElement);
+ tooltipinfo.popupElement = null;
+ }
+
+ }
+
+//
+// TooltipWaitDone()
+//
+
+SocialCalc.TooltipWaitDone = function() {
+
+ var tooltipinfo = SocialCalc.TooltipInfo;
+
+ tooltipinfo.timer = null;
+
+ SocialCalc.TooltipDisplay(tooltipinfo.tooltipElement);
+
+ }
+
+
+// *************************************
+//
+// Button functions:
+//
+// *************************************
+
+SocialCalc.ButtonInfo = {
+
+ // There is only one of these -- no "new" is done.
+ // Only one button operation can be active at a time.
+ // The registeredElements array is used to identify items.
+
+ // One item for each clickable element, each an object with:
+ // .element, .normalstyle, .hoverstyle, .downstyle, .repeatinterval, .functionobj
+ //
+ // .functionobj is an object with optional function objects for:
+ // mouseover, mouseout, mousedown, repeatinterval, mouseup, disabled
+
+ registeredElements: [],
+
+ // Items used during hover over an element, clicking, repeating, etc.
+
+ buttonElement: null, // item being processed, hover or down (.element is the actual element)
+ doingHover: false, // true if mouse is over one of our elements
+ buttonDown: false, // true if button down and buttonElement not null
+ timer: null, // timer object for repeating
+
+ // Used while processing an event
+
+ horizontalScroll: 0,
+ verticalScroll: 0,
+ clientX: 0,
+ clientY: 0
+
+ }
+
+//
+// ButtonRegister(element, paramobj, functionobj) - make element clickable
+//
+// The arguments (other than element) may be null (meaning no change for style and no repeat)
+// The paramobj has the optional normalstyle, hoverstyle, downstyle, repeatwait, repeatinterval settings
+
+SocialCalc.ButtonRegister = function(element, paramobj, functionobj) {
+
+ var buttoninfo = SocialCalc.ButtonInfo;
+
+ if (!paramobj) paramobj = {};
+
+ buttoninfo.registeredElements.push(
+ {name: paramobj.name, element: element, normalstyle: paramobj.normalstyle, hoverstyle: paramobj.hoverstyle, downstyle: paramobj.downstyle,
+ repeatwait: paramobj.repeatwait, repeatinterval: paramobj.repeatinterval, functionobj: functionobj}
+ );
+
+ if (element.addEventListener) { // DOM Level 2 -- Firefox, et al
+ element.addEventListener("mousedown", SocialCalc.ButtonMouseDown, false);
+ element.addEventListener("mouseover", SocialCalc.ButtonMouseOver, false);
+ element.addEventListener("mouseout", SocialCalc.ButtonMouseOut, false);
+ }
+ else if (element.attachEvent) { // IE 5+
+ element.attachEvent("onmousedown", SocialCalc.ButtonMouseDown);
+ element.attachEvent("onmouseover", SocialCalc.ButtonMouseOver);
+ element.attachEvent("onmouseout", SocialCalc.ButtonMouseOut);
+ }
+ else { // don't handle this
+ throw SocialCalc.Constants.s_BrowserNotSupported;
+ }
+
+ return;
+
+ }
+
+//
+// ButtonMouseOver(event)
+//
+
+SocialCalc.ButtonMouseOver = function(event) {
+
+ var e = event || window.event;
+
+ var buttoninfo = SocialCalc.ButtonInfo;
+
+ var bobj = SocialCalc.LookupElement(e.target || e.srcElement, buttoninfo.registeredElements);
+
+ if (!bobj) return;
+
+ if (buttoninfo.buttonDown) {
+ if (buttoninfo.buttonElement==bobj) {
+ buttoninfo.doingHover = true; // keep track whether we are on the pressed button or not
+ }
+ return;
+ }
+
+ if (buttoninfo.buttonElement &&
+ buttoninfo.buttonElement!=bobj && buttoninfo.doingHover) { // moved to a new one, undo hover there
+ SocialCalc.setStyles(buttoninfo.buttonElement.element, buttoninfo.buttonElement.normalstyle);
+ }
+
+ buttoninfo.buttonElement = bobj; // remember this one is hovering
+ buttoninfo.doingHover = true;
+
+ SocialCalc.setStyles(bobj.element, bobj.hoverstyle); // set style (if provided)
+
+ if (bobj && bobj.functionobj && bobj.functionobj.MouseOver) bobj.functionobj.MouseOver(e, buttoninfo, bobj);
+
+ return;
+
+ }
+
+//
+// ButtonMouseOut(event)
+//
+
+SocialCalc.ButtonMouseOut = function(event) {
+
+ var e = event || window.event;
+
+ var buttoninfo = SocialCalc.ButtonInfo;
+
+ if (buttoninfo.buttonDown) {
+ buttoninfo.doingHover = false; // keep track of overs and outs
+ return;
+ }
+
+ var bobj = SocialCalc.LookupElement(e.target || e.srcElement, buttoninfo.registeredElements);
+
+ if (buttoninfo.doingHover) { // if there was a hover, undo it
+ if (buttoninfo.buttonElement)
+ SocialCalc.setStyles(buttoninfo.buttonElement.element, buttoninfo.buttonElement.normalstyle);
+ buttoninfo.buttonElement = null;
+ buttoninfo.doingHover = false;
+ }
+
+ if (bobj && bobj.functionobj && bobj.functionobj.MouseOut) bobj.functionobj.MouseOut(e, buttoninfo, bobj);
+
+ return;
+
+ }
+
+//
+// ButtonMouseDown(event)
+//
+
+SocialCalc.ButtonMouseDown = function(event) {
+
+ var e = event || window.event;
+
+ var buttoninfo = SocialCalc.ButtonInfo;
+
+ var viewportinfo = SocialCalc.GetViewportInfo();
+
+ var bobj = SocialCalc.LookupElement(e.target || e.srcElement, buttoninfo.registeredElements);
+
+ if (!bobj) return; // not one of our elements
+
+ if (bobj && bobj.functionobj && bobj.functionobj.Disabled) {
+ if (bobj.functionobj.Disabled(e, buttoninfo, bobj)) {
+ return;
+ }
+ }
+
+ buttoninfo.buttonElement = bobj;
+ buttoninfo.buttonDown = true;
+
+ SocialCalc.setStyles(bobj.element, buttoninfo.buttonElement.downstyle);
+
+ // Register event handler for mouse up
+
+ // Event code from JavaScript, Flanagan, 5th Edition, pg. 422
+ if (document.addEventListener) { // DOM Level 2 -- Firefox, et al
+ document.addEventListener("mouseup", SocialCalc.ButtonMouseUp, true); // capture everywhere
+ }
+ else if (bobj.element.attachEvent) { // IE 5+
+ bobj.element.setCapture();
+ bobj.element.attachEvent("onmouseup", SocialCalc.ButtonMouseUp);
+ bobj.element.attachEvent("onlosecapture", SocialCalc.ButtonMouseUp);
+ }
+ if (e.stopPropagation) e.stopPropagation(); // DOM Level 2
+ else e.cancelBubble = true; // IE 5+
+ if (e.preventDefault) e.preventDefault(); // DOM Level 2
+ else e.returnValue = false; // IE 5+
+
+ buttoninfo.horizontalScroll = viewportinfo.horizontalScroll;
+ buttoninfo.verticalScroll = viewportinfo.verticalScroll;
+ buttoninfo.clientX = e.clientX + buttoninfo.horizontalScroll; // get document-relative coordinates
+ buttoninfo.clientY = e.clientY + buttoninfo.verticalScroll;
+
+ if (bobj && bobj.functionobj && bobj.functionobj.MouseDown) bobj.functionobj.MouseDown(e, buttoninfo, bobj);
+
+ if (bobj.repeatwait) { // if a repeat wait is set, then starting waiting for first repetition
+ buttoninfo.timer = window.setTimeout(SocialCalc.ButtonRepeat, bobj.repeatwait);
+ }
+
+ return;
+
+ }
+
+//
+// ButtonMouseUp(event)
+//
+
+SocialCalc.ButtonMouseUp = function(event) {
+
+ var e = event || window.event;
+
+ var buttoninfo = SocialCalc.ButtonInfo;
+ var bobj = buttoninfo.buttonElement;
+
+ if (buttoninfo.timer) { // if repeating, cancel it
+ window.clearTimeout(buttoninfo.timer); // cancel timer
+ buttoninfo.timer = null;
+ }
+
+ if (!buttoninfo.buttonDown) return; // already did this (e.g., in IE, releaseCapture fires losecapture)
+
+ if (e.stopPropagation) e.stopPropagation(); // DOM Level 2
+ else e.cancelBubble = true; // IE 5+
+ if (e.preventDefault) e.preventDefault(); // DOM Level 2
+ else e.returnValue = false; // IE 5+
+
+ if (document.removeEventListener) { // DOM Level 2
+ document.removeEventListener("mouseup", SocialCalc.ButtonMouseUp, true);
+ }
+ else if (document.detachEvent) { // IE
+ bobj.element.detachEvent("onlosecapture", SocialCalc.ButtonMouseUp);
+ bobj.element.detachEvent("onmouseup", SocialCalc.ButtonMouseUp);
+ bobj.element.releaseCapture();
+ }
+
+ if (buttoninfo.buttonElement.downstyle) {
+ if (buttoninfo.doingHover)
+ SocialCalc.setStyles(bobj.element, buttoninfo.buttonElement.hoverstyle);
+ else
+ SocialCalc.setStyles(bobj.element, buttoninfo.buttonElement.normalstyle);
+ }
+
+ buttoninfo.buttonDown = false;
+
+ if (bobj && bobj.functionobj && bobj.functionobj.MouseUp) bobj.functionobj.MouseUp(e, buttoninfo, bobj);
+
+ }
+
+//
+// ButtonRepeat()
+//
+
+SocialCalc.ButtonRepeat = function() {
+
+ var buttoninfo = SocialCalc.ButtonInfo;
+ var bobj = buttoninfo.buttonElement;
+
+ if (!bobj) return;
+
+ if (bobj && bobj.functionobj && bobj.functionobj.Repeat) bobj.functionobj.Repeat(null, buttoninfo, bobj);
+
+ buttoninfo.timer = window.setTimeout(SocialCalc.ButtonRepeat, bobj.repeatinterval || 100);
+
+ }
+
+// *************************************
+//
+// MouseWheel functions:
+//
+// *************************************
+
+SocialCalc.MouseWheelInfo = {
+
+ // There is only one of these -- no "new" is done.
+ // The mousewheel only affects the one area the mouse pointer is over
+ // The registeredElements array is used to identify items.
+
+ // One item for each element to respond to the mousewheel, each an object with:
+ // .element, .functionobj
+
+ registeredElements: []
+
+ }
+
+//
+// MouseWheelRegister(element, functionobj) - make element respond to mousewheel
+//
+
+SocialCalc.MouseWheelRegister = function(element, functionobj) {
+
+ var mousewheelinfo = SocialCalc.MouseWheelInfo;
+
+ mousewheelinfo.registeredElements.push(
+ {element: element, functionobj: functionobj}
+ );
+
+ if (element.addEventListener) { // DOM Level 2 -- Firefox, et al
+ element.addEventListener("DOMMouseScroll", SocialCalc.ProcessMouseWheel, false);
+ element.addEventListener("mousewheel", SocialCalc.ProcessMouseWheel, false); // Opera needs this
+ }
+ else if (element.attachEvent) { // IE 5+
+ element.attachEvent("onmousewheel", SocialCalc.ProcessMouseWheel);
+ }
+ else { // don't handle this
+ throw SocialCalc.Constants.s_BrowserNotSupported;
+ }
+
+ return;
+
+ }
+
+SocialCalc.ProcessMouseWheel = function(e) {
+
+ var event = e || window.event;
+ var delta;
+
+ if (SocialCalc.Keyboard.passThru) return; // ignore
+
+ var mousewheelinfo = SocialCalc.MouseWheelInfo;
+ var ele = event.target || event.srcElement; // source object is often within what we want
+ var wobj;
+
+ for (wobj=null; !wobj && ele; ele=ele.parentNode) { // go up tree looking for one of our elements
+ wobj = SocialCalc.LookupElement(ele, mousewheelinfo.registeredElements);
+ }
+ if (!wobj) return; // not one of our elements
+
+ if (event.wheelDelta) {
+ delta = event.wheelDelta/120;
+ }
+ else delta = -event.detail/3;
+ if (!delta) delta = 0;
+
+ if (wobj.functionobj && wobj.functionobj.WheelMove) wobj.functionobj.WheelMove(event, delta, mousewheelinfo, wobj);
+
+ if (event.preventDefault) event.preventDefault();
+ event.returnValue = false;
+
+ }
+
+// *************************************
+//
+// Keyboard functions:
+//
+// For more information about keyboard handling, see: http://unixpapa.com/js/key.html
+//
+// *************************************
+
+SocialCalc.keyboardTables = {
+
+ specialKeysCommon: {
+ 8: "[backspace]", 9: "[tab]", 13: "[enter]", 25: "[tab]", 27: "[esc]", 33: "[pgup]", 34: "[pgdn]",
+ 35: "[end]", 36: "[home]", 37: "[aleft]", 38: "[aup]", 39: "[aright]", 40: "[adown]", 45: "[ins]",
+ 46: "[del]", 113: "[f2]"
+ },
+
+ specialKeysIE: {
+ 8: "[backspace]", 9: "[tab]", 13: "[enter]", 25: "[tab]", 27: "[esc]", 33: "[pgup]", 34: "[pgdn]",
+ 35: "[end]", 36: "[home]", 37: "[aleft]", 38: "[aup]", 39: "[aright]", 40: "[adown]", 45: "[ins]",
+ 46: "[del]", 113: "[f2]"
+ },
+
+ controlKeysIE: {
+ 67: "[ctrl-c]",
+ 83: "[ctrl-s]",
+ 86: "[ctrl-v]",
+ 88: "[ctrl-x]",
+ 90: "[ctrl-z]"
+ },
+
+ specialKeysOpera: {
+ 8: "[backspace]", 9: "[tab]", 13: "[enter]", 25: "[tab]", 27: "[esc]", 33: "[pgup]", 34: "[pgdn]",
+ 35: "[end]", 36: "[home]", 37: "[aleft]", 38: "[aup]", 39: "[aright]", 40: "[adown]",
+ 45: "[ins]", // issues with releases before 9.5 - same as "-" ("-" changed in 9.5)
+ 46: "[del]", // issues with releases before 9.5 - same as "." ("." changed in 9.5)
+ 113: "[f2]"
+ },
+
+ controlKeysOpera: {
+ 67: "[ctrl-c]",
+ 83: "[ctrl-s]",
+ 86: "[ctrl-v]",
+ 88: "[ctrl-x]",
+ 90: "[ctrl-z]"
+ },
+
+ specialKeysSafari: {
+ 8: "[backspace]", 9: "[tab]", 13: "[enter]", 25: "[tab]", 27: "[esc]", 63232: "[aup]", 63233: "[adown]",
+ 63234: "[aleft]", 63235: "[aright]", 63272: "[del]", 63273: "[home]", 63275: "[end]", 63276: "[pgup]",
+ 63277: "[pgdn]", 63237: "[f2]"
+ },
+
+ controlKeysSafari: {
+ 99: "[ctrl-c]",
+ 115: "[ctrl-s]",
+ 118: "[ctrl-v]",
+ 120: "[ctrl-x]",
+ 122: "[ctrl-z]"
+ },
+
+ ignoreKeysSafari: {
+ 63236: "[f1]", 63238: "[f3]", 63239: "[f4]", 63240: "[f5]", 63241: "[f6]", 63242: "[f7]",
+ 63243: "[f8]", 63244: "[f9]", 63245: "[f10]", 63246: "[f11]", 63247: "[f12]", 63289: "[numlock]"
+ },
+
+ specialKeysFirefox: {
+ 8: "[backspace]", 9: "[tab]", 13: "[enter]", 25: "[tab]", 27: "[esc]", 33: "[pgup]", 34: "[pgdn]",
+ 35: "[end]", 36: "[home]", 37: "[aleft]", 38: "[aup]", 39: "[aright]", 40: "[adown]", 45: "[ins]",
+ 46: "[del]", 113: "[f2]"
+ },
+
+ controlKeysFirefox: {
+ 99: "[ctrl-c]",
+ 115: "[ctrl-s]",
+ 118: "[ctrl-v]",
+ 120: "[ctrl-x]",
+ 122: "[ctrl-z]"
+ },
+
+ ignoreKeysFirefox: {
+ 16: "[shift]", 17: "[ctrl]", 18: "[alt]", 20: "[capslock]", 19: "[pause]", 44: "[printscreen]",
+ 91: "[windows]", 92: "[windows]", 112: "[f1]", 114: "[f3]", 115: "[f4]", 116: "[f5]",
+ 117: "[f6]", 118: "[f7]", 119: "[f8]", 120: "[f9]", 121: "[f10]", 122: "[f11]", 123: "[f12]",
+ 144: "[numlock]", 145: "[scrolllock]", 224: "[cmd]"
+ }
+ }
+
+SocialCalc.Keyboard = {
+ areListener: false, // if true, we have been installed as a listener for keyboard events
+ focusTable: null, // the table editor object that gets keystrokes or null
+ passThru: null, // if not null, control element with focus to pass keyboard events to (has blur method), or "true"
+ didProcessKey: false, // did SocialCalc.ProcessKey in keydown
+ statusFromProcessKey: false, // the status from the keydown SocialCalc.ProcessKey
+ repeatingKeyPress: false, // some browsers (Opera, Gecko Mac) repeat special keys as KeyPress not KeyDown
+ chForProcessKey: "" // remember so can do repeat in those cases
+ };
+
+SocialCalc.KeyboardSetFocus = function(editor) {
+
+ SocialCalc.Keyboard.focusTable = editor;
+
+ if (!SocialCalc.Keyboard.areListener) {
+ document.onkeydown = SocialCalc.ProcessKeyDown;
+ document.onkeypress = SocialCalc.ProcessKeyPress;
+ SocialCalc.Keyboard.areListener = true;
+ }
+ if (SocialCalc.Keyboard.passThru) {
+ if (SocialCalc.Keyboard.passThru.blur) {
+ SocialCalc.Keyboard.passThru.blur();
+ }
+ SocialCalc.Keyboard.passThru = null;
+ }
+ window.focus();
+ }
+
+SocialCalc.KeyboardFocus = function() {
+
+ SocialCalc.Keyboard.passThru = null;
+ window.focus();
+
+ }
+
+SocialCalc.ProcessKeyDown = function(e) {
+
+ var kt = SocialCalc.keyboardTables;
+ kt.didProcessKey = false; // always start false
+ kt.statusFromProcessKey = false;
+ kt.repeatingKeyPress = false;
+
+ var ch="";
+ var status=true;
+
+ if (SocialCalc.Keyboard.passThru) return; // ignore
+
+ e = e || window.event;
+
+ if (e.which==undefined) { // IE
+ ch = kt.specialKeysCommon[e.keyCode];
+ if (!ch) {
+ if (e.ctrlKey) {
+ ch=kt.controlKeysIE[e.keyCode];
+ }
+ if (!ch)
+ return true;
+ }
+ status = SocialCalc.ProcessKey(ch, e);
+
+ if (!status) {
+ if (e.preventDefault) e.preventDefault();
+ e.returnValue = false;
+ }
+ }
+
+ else {
+ ch = kt.specialKeysCommon[e.keyCode];
+ if (!ch) {
+// return true;
+ if (e.ctrlKey || e.metaKey) {
+ ch=kt.controlKeysIE[e.keyCode]; // this works here
+ }
+ if (!ch)
+ return true;
+ }
+
+ status = SocialCalc.ProcessKey(ch, e); // process the key
+ kt.didProcessKey = true; // remember what happened
+ kt.statusFromProcessKey = status;
+ kt.chForProcessKey = ch;
+ }
+
+ return status;
+
+ }
+
+SocialCalc.ProcessKeyPress = function(e) {
+
+ var kt = SocialCalc.keyboardTables;
+
+ var ch="";
+
+ e = e || window.event;
+
+ if (SocialCalc.Keyboard.passThru) return; // ignore
+ if (kt.didProcessKey) { // already processed this key
+ if (kt.repeatingKeyPress) {
+ return SocialCalc.ProcessKey(kt.chForProcessKey, e); // process the same key as on KeyDown
+ }
+ else {
+ kt.repeatingKeyPress = true; // see if get another KeyPress before KeyDown
+ return kt.statusFromProcessKey; // do what it said to do
+ }
+ }
+
+ if (e.which==undefined) { // IE
+ // Note: Esc and Enter will come through here, too, if not stopped at KeyDown
+ ch=String.fromCharCode(e.keyCode); // convert to a character (special chars handled at ev1)
+ }
+
+ else { // not IE
+ if (!e.which)
+ return false; // ignore - special key
+ if (e.charCode==undefined) { // Opera
+ if (e.which!=0) { // character
+ if (e.which<32 || e.which==144) { // special char (144 is numlock)
+ ch = kt.specialKeysOpera[e.which];
+ if (ch) {
+ return true;
+ }
+ }
+ else {
+ if (e.ctrlKey) {
+ ch=kt.controlKeysOpera[e.keyCode];
+ }
+ else {
+ ch = String.fromCharCode(e.which);
+ }
+ }
+ }
+ else { // special char
+ return true;
+ }
+ }
+
+ else if (e.keyCode==0 && e.charCode==0) { // OLPC Fn key or something
+ return; // ignore
+ }
+
+ else if (e.keyCode==e.charCode) { // Safari
+ ch = kt.specialKeysSafari[e.keyCode];
+ if (!ch) {
+ if (kt.ignoreKeysSafari[e.keyCode]) // pass this through
+ return true;
+ if (e.metaKey) {
+ ch=kt.controlKeysSafari[e.keyCode];
+ }
+ else {
+ ch = String.fromCharCode(e.which);
+ }
+ }
+ }
+
+ else { // Firefox
+ if (kt.specialKeysFirefox[e.keyCode]) {
+ return true;
+ }
+ ch = String.fromCharCode(e.which);
+ if (e.ctrlKey || e.metaKey) {
+ ch = kt.controlKeysFirefox[e.which];
+ }
+ }
+ }
+
+ var status = SocialCalc.ProcessKey(ch, e);
+
+ if (!status) {
+ if (e.preventDefault) e.preventDefault();
+ e.returnValue = false;
+ }
+
+ return status;
+
+ }
+
+/*
+ *
+ * OLD ProcessKeyDown and ProcessKeyPress -- replaced for handling newer browsers, including Safari 3.1 and Opera 9.5
+ *
+
+SocialCalc.ProcessKeyDown = function(e) {
+
+ var kt = SocialCalc.keyboardTables;
+
+ var ch="";
+ var status=true;
+
+ if (SocialCalc.Keyboard.passThru) return; // ignore
+
+ e = e || window.event;
+
+ if (e.which==undefined) { // IE
+ ch = kt.specialKeysIE[e.keyCode];
+ if (!ch) {
+ if (e.ctrlKey) {
+ ch=kt.controlKeysIE[e.keyCode];
+ }
+ if (!ch)
+ return true;
+ }
+
+ status = SocialCalc.ProcessKey(ch, e);
+
+ if (!status) {
+ if (e.preventDefault) e.preventDefault();
+ e.returnValue = false;
+ }
+ }
+
+ else { // don't do anything for other browsers - wait for keyPress
+ ; // special key repeats are done as keypress in those browsers
+ }
+
+ return status;
+
+ }
+
+SocialCalc.ProcessKeyPress = function(e) {
+
+ var kt = SocialCalc.keyboardTables;
+
+ var ch="";
+
+ if (SocialCalc.Keyboard.passThru) return; // ignore
+
+ e = e || window.event;
+
+ if (e.which==undefined) { // IE
+ // Note: Esc and Enter will come through here, too, if not stopped at KeyDown
+ ch=String.fromCharCode(e.keyCode); // convert to a character (special chars handled at ev1)
+ }
+
+ else { // not IE
+ if (e.charCode==undefined) { // Opera
+ if (e.which!=0) { // character
+ if (e.which<32) { // special char
+ ch = kt.specialKeysOpera[e.keyCode];
+ if (!ch)
+ return true;
+ }
+ else {
+ if (e.ctrlKey) {
+ ch=kt.controlKeysOpera[e.keyCode];
+ }
+ else {
+ ch = String.fromCharCode(e.which);
+ }
+ }
+ }
+ else { // special char
+ ch = kt.specialKeysOpera[e.keyCode];
+ if (!ch)
+ return true;
+ }
+ }
+
+ else if (e.keyCode==0 && e.charCode==0) { // OLPC Fn key or something
+ return; // ignore
+ }
+
+ else if (e.keyCode==e.charCode) { // Safari
+ ch = kt.specialKeysSafari[e.keyCode];
+ if (!ch) {
+ if (kt.ignoreKeysSafari[e.keyCode]) // pass this through
+ return true;
+ if (e.metaKey) {
+ ch=kt.controlKeysSafari[e.keyCode];
+ }
+ else {
+ ch = String.fromCharCode(e.which);
+ }
+ }
+ }
+
+ else { // Firefox
+ ch = kt.specialKeysFirefox[e.keyCode];
+ if (!ch) {
+ if (kt.ignoreKeysFirefox[e.keyCode]) // pass this through
+ return true;
+ if (e.which) { // normal char
+ if (e.ctrlKey || e.metaKey) {
+ ch = kt.controlKeysFirefox[e.which];
+ }
+ else {
+ ch = String.fromCharCode(e.which);
+ }
+ }
+ else { // usually a special char
+ return true; // old Firefox gives extra, empty keyPress for "/" - ignore
+ }
+ }
+ }
+ }
+
+ var status = SocialCalc.ProcessKey(ch, e);
+
+ if (!status) {
+ if (e.preventDefault) e.preventDefault();
+ e.returnValue = false;
+ }
+
+ return status;
+
+ }
+*/
+
+//
+// status = SocialCalc.ProcessKey(ch, e)
+//
+// Take a key representation as a character string and dispatch to appropriate routine
+//
+
+SocialCalc.ProcessKey = function (ch, e) {
+
+ var ft = SocialCalc.Keyboard.focusTable;
+
+ if (!ft) return true; // we're not handling it -- let browser do default
+
+ return ft.EditorProcessKey(ch, e);
+
+ }
+
+
diff --git a/web/xocom.js b/web/xocom.js
new file mode 100644
index 0000000..e3e5651
--- /dev/null
+++ b/web/xocom.js
@@ -0,0 +1,3595 @@
+(function(){
+/*
+ * jQuery 1.2.3 - New Wave Javascript
+ *
+ * Copyright (c) 2008 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $
+ * $Rev: 4663 $
+ */
+
+// Map over jQuery in case of overwrite
+if ( window.jQuery )
+ var _jQuery = window.jQuery;
+
+var jQuery = window.jQuery = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.prototype.init( selector, context );
+};
+
+// Map over the $ in case of overwrite
+if ( window.$ )
+ var _$ = window.$;
+
+// Map the jQuery namespace to the '$' one
+window.$ = jQuery;
+
+// A simple way to check for HTML strings or ID strings
+// (both of which we optimize for)
+var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;
+
+// Is it a simple selector
+var isSimple = /^.[^:#\[\.]*$/;
+
+jQuery.fn = jQuery.prototype = {
+ init: function( selector, context ) {
+ // Make sure that a selection was provided
+ selector = selector || document;
+
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this[0] = selector;
+ this.length = 1;
+ return this;
+
+ // Handle HTML strings
+ } else if ( typeof selector == "string" ) {
+ // Are we dealing with HTML string or an ID?
+ var match = quickExpr.exec( selector );
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] )
+ selector = jQuery.clean( [ match[1] ], context );
+
+ // HANDLE: $("#id")
+ else {
+ var elem = document.getElementById( match[3] );
+
+ // Make sure an element was located
+ if ( elem )
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id != match[3] )
+ return jQuery().find( selector );
+
+ // Otherwise, we inject the element directly into the jQuery object
+ else {
+ this[0] = elem;
+ this.length = 1;
+ return this;
+ }
+
+ else
+ selector = [];
+ }
+
+ // HANDLE: $(expr, [context])
+ // (which is just equivalent to: $(content).find(expr)
+ } else
+ return new jQuery( context ).find( selector );
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) )
+ return new jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
+
+ return this.setArray(
+ // HANDLE: $(array)
+ selector.constructor == Array && selector ||
+
+ // HANDLE: $(arraylike)
+ // Watch for when an array-like object, contains DOM nodes, is passed in as the selector
+ (selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) ||
+
+ // HANDLE: $(*)
+ [ selector ] );
+ },
+
+ // The current version of jQuery being used
+ jquery: "1.2.3",
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ return this.length;
+ },
+
+ // The number of elements contained in the matched element set
+ length: 0,
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num == undefined ?
+
+ // Return a 'clean' array
+ jQuery.makeArray( this ) :
+
+ // Return just the object
+ this[ num ];
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems ) {
+ // Build a new jQuery matched element set
+ var ret = jQuery( elems );
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Force the current matched set of elements to become
+ // the specified array of elements (destroying the stack in the process)
+ // You should use pushStack() in order to do this, but maintain the stack
+ setArray: function( elems ) {
+ // Resetting the length to 0, then using the native Array push
+ // is a super-fast way to populate an object with array-like properties
+ this.length = 0;
+ Array.prototype.push.apply( this, elems );
+
+ return this;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+ var ret = -1;
+
+ // Locate the position of the desired element
+ this.each(function(i){
+ if ( this == elem )
+ ret = i;
+ });
+
+ return ret;
+ },
+
+ attr: function( name, value, type ) {
+ var options = name;
+
+ // Look for the case where we're accessing a style value
+ if ( name.constructor == String )
+ if ( value == undefined )
+ return this.length && jQuery[ type || "attr" ]( this[0], name ) || undefined;
+
+ else {
+ options = {};
+ options[ name ] = value;
+ }
+
+ // Check to see if we're setting style values
+ return this.each(function(i){
+ // Set all the styles
+ for ( name in options )
+ jQuery.attr(
+ type ?
+ this.style :
+ this,
+ name, jQuery.prop( this, options[ name ], type, i, name )
+ );
+ });
+ },
+
+ css: function( key, value ) {
+ // ignore negative width and height values
+ if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
+ value = undefined;
+ return this.attr( key, value, "curCSS" );
+ },
+
+ text: function( text ) {
+ if ( typeof text != "object" && text != null )
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+
+ var ret = "";
+
+ jQuery.each( text || this, function(){
+ jQuery.each( this.childNodes, function(){
+ if ( this.nodeType != 8 )
+ ret += this.nodeType != 1 ?
+ this.nodeValue :
+ jQuery.fn.text( [ this ] );
+ });
+ });
+
+ return ret;
+ },
+
+ wrapAll: function( html ) {
+ if ( this[0] )
+ // The elements to wrap the target around
+ jQuery( html, this[0].ownerDocument )
+ .clone()
+ .insertBefore( this[0] )
+ .map(function(){
+ var elem = this;
+
+ while ( elem.firstChild )
+ elem = elem.firstChild;
+
+ return elem;
+ })
+ .append(this);
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ return this.each(function(){
+ jQuery( this ).contents().wrapAll( html );
+ });
+ },
+
+ wrap: function( html ) {
+ return this.each(function(){
+ jQuery( this ).wrapAll( html );
+ });
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, false, function(elem){
+ if (this.nodeType == 1)
+ this.appendChild( elem );
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, true, function(elem){
+ if (this.nodeType == 1)
+ this.insertBefore( elem, this.firstChild );
+ });
+ },
+
+ before: function() {
+ return this.domManip(arguments, false, false, function(elem){
+ this.parentNode.insertBefore( elem, this );
+ });
+ },
+
+ after: function() {
+ return this.domManip(arguments, false, true, function(elem){
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ });
+ },
+
+ end: function() {
+ return this.prevObject || jQuery( [] );
+ },
+
+ find: function( selector ) {
+ var elems = jQuery.map(this, function(elem){
+ return jQuery.find( selector, elem );
+ });
+
+ return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
+ jQuery.unique( elems ) :
+ elems );
+ },
+
+ clone: function( events ) {
+ // Do the clone
+ var ret = this.map(function(){
+ if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
+ // IE copies events bound via attachEvent when
+ // using cloneNode. Calling detachEvent on the
+ // clone will also remove the events from the orignal
+ // In order to get around this, we use innerHTML.
+ // Unfortunately, this means some modifications to
+ // attributes in IE that are actually only stored
+ // as properties will not be copied (such as the
+ // the name attribute on an input).
+ var clone = this.cloneNode(true),
+ container = document.createElement("div");
+ container.appendChild(clone);
+ return jQuery.clean([container.innerHTML])[0];
+ } else
+ return this.cloneNode(true);
+ });
+
+ // Need to set the expando to null on the cloned set if it exists
+ // removeData doesn't work here, IE removes it from the original as well
+ // this is primarily for IE but the data expando shouldn't be copied over in any browser
+ var clone = ret.find("*").andSelf().each(function(){
+ if ( this[ expando ] != undefined )
+ this[ expando ] = null;
+ });
+
+ // Copy the events from the original to the clone
+ if ( events === true )
+ this.find("*").andSelf().each(function(i){
+ if (this.nodeType == 3)
+ return;
+ var events = jQuery.data( this, "events" );
+
+ for ( var type in events )
+ for ( var handler in events[ type ] )
+ jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
+ });
+
+ // Return the cloned set
+ return ret;
+ },
+
+ filter: function( selector ) {
+ return this.pushStack(
+ jQuery.isFunction( selector ) &&
+ jQuery.grep(this, function(elem, i){
+ return selector.call( elem, i );
+ }) ||
+
+ jQuery.multiFilter( selector, this ) );
+ },
+
+ not: function( selector ) {
+ if ( selector.constructor == String )
+ // test special case where just one selector is passed in
+ if ( isSimple.test( selector ) )
+ return this.pushStack( jQuery.multiFilter( selector, this, true ) );
+ else
+ selector = jQuery.multiFilter( selector, this );
+
+ var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
+ return this.filter(function() {
+ return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
+ });
+ },
+
+ add: function( selector ) {
+ return !selector ? this : this.pushStack( jQuery.merge(
+ this.get(),
+ selector.constructor == String ?
+ jQuery( selector ).get() :
+ selector.length != undefined && (!selector.nodeName || jQuery.nodeName(selector, "form")) ?
+ selector : [selector] ) );
+ },
+
+ is: function( selector ) {
+ return selector ?
+ jQuery.multiFilter( selector, this ).length > 0 :
+ false;
+ },
+
+ hasClass: function( selector ) {
+ return this.is( "." + selector );
+ },
+
+ val: function( value ) {
+ if ( value == undefined ) {
+
+ if ( this.length ) {
+ var elem = this[0];
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName( elem, "select" ) ) {
+ var index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type == "select-one";
+
+ // Nothing was selected
+ if ( index < 0 )
+ return null;
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[ i ];
+
+ if ( option.selected ) {
+ // Get the specifc value for the option
+ value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
+
+ // We don't need an array for one selects
+ if ( one )
+ return value;
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ return values;
+
+ // Everything else, we just grab the value
+ } else
+ return (this[0].value || "").replace(/\r/g, "");
+
+ }
+
+ return undefined;
+ }
+
+ return this.each(function(){
+ if ( this.nodeType != 1 )
+ return;
+
+ if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
+ this.checked = (jQuery.inArray(this.value, value) >= 0 ||
+ jQuery.inArray(this.name, value) >= 0);
+
+ else if ( jQuery.nodeName( this, "select" ) ) {
+ var values = value.constructor == Array ?
+ value :
+ [ value ];
+
+ jQuery( "option", this ).each(function(){
+ this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
+ jQuery.inArray( this.text, values ) >= 0);
+ });
+
+ if ( !values.length )
+ this.selectedIndex = -1;
+
+ } else
+ this.value = value;
+ });
+ },
+
+ html: function( value ) {
+ return value == undefined ?
+ (this.length ?
+ this[0].innerHTML :
+ null) :
+ this.empty().append( value );
+ },
+
+ replaceWith: function( value ) {
+ return this.after( value ).remove();
+ },
+
+ eq: function( i ) {
+ return this.slice( i, i + 1 );
+ },
+
+ slice: function() {
+ return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function(elem, i){
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ },
+
+ data: function( key, value ){
+ var parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if ( value == null ) {
+ var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+ if ( data == undefined && this.length )
+ data = jQuery.data( this[0], key );
+
+ return data == null && parts[1] ?
+ this.data( parts[0] ) :
+ data;
+ } else
+ return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
+ jQuery.data( this, key, value );
+ });
+ },
+
+ removeData: function( key ){
+ return this.each(function(){
+ jQuery.removeData( this, key );
+ });
+ },
+
+ domManip: function( args, table, reverse, callback ) {
+ var clone = this.length > 1, elems;
+
+ return this.each(function(){
+ if ( !elems ) {
+ elems = jQuery.clean( args, this.ownerDocument );
+
+ if ( reverse )
+ elems.reverse();
+ }
+
+ var obj = this;
+
+ if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
+ obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
+
+ var scripts = jQuery( [] );
+
+ jQuery.each(elems, function(){
+ var elem = clone ?
+ jQuery( this ).clone( true )[0] :
+ this;
+
+ // execute all scripts after the elements have been injected
+ if ( jQuery.nodeName( elem, "script" ) ) {
+ scripts = scripts.add( elem );
+ } else {
+ // Remove any inner scripts for later evaluation
+ if ( elem.nodeType == 1 )
+ scripts = scripts.add( jQuery( "script", elem ).remove() );
+
+ // Inject the elements into the document
+ callback.call( obj, elem );
+ }
+ });
+
+ scripts.each( evalScript );
+ });
+ }
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.prototype.init.prototype = jQuery.prototype;
+
+function evalScript( i, elem ) {
+ if ( elem.src )
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+
+ else
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+
+ if ( elem.parentNode )
+ elem.parentNode.removeChild( elem );
+}
+
+jQuery.extend = jQuery.fn.extend = function() {
+ // copy reference to target object
+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
+
+ // Handle a deep copy situation
+ if ( target.constructor == Boolean ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target != "object" && typeof target != "function" )
+ target = {};
+
+ // extend jQuery itself if only one argument is passed
+ if ( length == 1 ) {
+ target = this;
+ i = 0;
+ }
+
+ for ( ; i < length; i++ )
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null )
+ // Extend the base object
+ for ( var name in options ) {
+ // Prevent never-ending loop
+ if ( target === options[ name ] )
+ continue;
+
+ // Recurse if we're merging object values
+ if ( deep && options[ name ] && typeof options[ name ] == "object" && target[ name ] && !options[ name ].nodeType )
+ target[ name ] = jQuery.extend( target[ name ], options[ name ] );
+
+ // Don't bring in undefined values
+ else if ( options[ name ] != undefined )
+ target[ name ] = options[ name ];
+
+ }
+
+ // Return the modified object
+ return target;
+};
+
+var expando = "jQuery" + (new Date()).getTime(), uuid = 0, windowData = {};
+
+// exclude the following css properties to add px
+var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i;
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ window.$ = _$;
+
+ if ( deep )
+ window.jQuery = _jQuery;
+
+ return jQuery;
+ },
+
+ // See test/unit/core.js for details concerning this function.
+ isFunction: function( fn ) {
+ return !!fn && typeof fn != "string" && !fn.nodeName &&
+ fn.constructor != Array && /function/i.test( fn + "" );
+ },
+
+ // check if an element is in a (or is an) XML document
+ isXMLDoc: function( elem ) {
+ return elem.documentElement && !elem.body ||
+ elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
+ },
+
+ // Evalulates a script in a global context
+ globalEval: function( data ) {
+ data = jQuery.trim( data );
+
+ if ( data ) {
+ // Inspired by code by Andrea Giammarchi
+ // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+ var head = document.getElementsByTagName("head")[0] || document.documentElement,
+ script = document.createElement("script");
+
+ script.type = "text/javascript";
+ if ( jQuery.browser.msie )
+ script.text = data;
+ else
+ script.appendChild( document.createTextNode( data ) );
+
+ head.appendChild( script );
+ head.removeChild( script );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
+ },
+
+ cache: {},
+
+ data: function( elem, name, data ) {
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ];
+
+ // Compute a unique ID for the element
+ if ( !id )
+ id = elem[ expando ] = ++uuid;
+
+ // Only generate the data cache if we're
+ // trying to access or manipulate it
+ if ( name && !jQuery.cache[ id ] )
+ jQuery.cache[ id ] = {};
+
+ // Prevent overriding the named cache with undefined values
+ if ( data != undefined )
+ jQuery.cache[ id ][ name ] = data;
+
+ // Return the named cache data, or the ID for the element
+ return name ?
+ jQuery.cache[ id ][ name ] :
+ id;
+ },
+
+ removeData: function( elem, name ) {
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ];
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( jQuery.cache[ id ] ) {
+ // Remove the section of cache data
+ delete jQuery.cache[ id ][ name ];
+
+ // If we've removed all the data, remove the element's cache
+ name = "";
+
+ for ( name in jQuery.cache[ id ] )
+ break;
+
+ if ( !name )
+ jQuery.removeData( elem );
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ // Clean up the element expando
+ try {
+ delete elem[ expando ];
+ } catch(e){
+ // IE has trouble directly removing the expando
+ // but it's ok with using removeAttribute
+ if ( elem.removeAttribute )
+ elem.removeAttribute( expando );
+ }
+
+ // Completely remove the data cache
+ delete jQuery.cache[ id ];
+ }
+ },
+
+ // args is for internal usage only
+ each: function( object, callback, args ) {
+ if ( args ) {
+ if ( object.length == undefined ) {
+ for ( var name in object )
+ if ( callback.apply( object[ name ], args ) === false )
+ break;
+ } else
+ for ( var i = 0, length = object.length; i < length; i++ )
+ if ( callback.apply( object[ i ], args ) === false )
+ break;
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( object.length == undefined ) {
+ for ( var name in object )
+ if ( callback.call( object[ name ], name, object[ name ] ) === false )
+ break;
+ } else
+ for ( var i = 0, length = object.length, value = object[0];
+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
+ }
+
+ return object;
+ },
+
+ prop: function( elem, value, type, i, name ) {
+ // Handle executable functions
+ if ( jQuery.isFunction( value ) )
+ value = value.call( elem, i );
+
+ // Handle passing in a number to a CSS property
+ return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
+ value + "px" :
+ value;
+ },
+
+ className: {
+ // internal only, use addClass("class")
+ add: function( elem, classNames ) {
+ jQuery.each((classNames || "").split(/\s+/), function(i, className){
+ if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
+ elem.className += (elem.className ? " " : "") + className;
+ });
+ },
+
+ // internal only, use removeClass("class")
+ remove: function( elem, classNames ) {
+ if (elem.nodeType == 1)
+ elem.className = classNames != undefined ?
+ jQuery.grep(elem.className.split(/\s+/), function(className){
+ return !jQuery.className.has( classNames, className );
+ }).join(" ") :
+ "";
+ },
+
+ // internal only, use is(".class")
+ has: function( elem, className ) {
+ return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
+ }
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ var old = {};
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ callback.call( elem );
+
+ // Revert the old values
+ for ( var name in options )
+ elem.style[ name ] = old[ name ];
+ },
+
+ css: function( elem, name, force ) {
+ if ( name == "width" || name == "height" ) {
+ var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
+
+ function getWH() {
+ val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
+ var padding = 0, border = 0;
+ jQuery.each( which, function() {
+ padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
+ border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
+ });
+ val -= Math.round(padding + border);
+ }
+
+ if ( jQuery(elem).is(":visible") )
+ getWH();
+ else
+ jQuery.swap( elem, props, getWH );
+
+ return Math.max(0, val);
+ }
+
+ return jQuery.curCSS( elem, name, force );
+ },
+
+ curCSS: function( elem, name, force ) {
+ var ret;
+
+ // A helper method for determining if an element's values are broken
+ function color( elem ) {
+ if ( !jQuery.browser.safari )
+ return false;
+
+ var ret = document.defaultView.getComputedStyle( elem, null );
+ return !ret || ret.getPropertyValue("color") == "";
+ }
+
+ // We need to handle opacity special in IE
+ if ( name == "opacity" && jQuery.browser.msie ) {
+ ret = jQuery.attr( elem.style, "opacity" );
+
+ return ret == "" ?
+ "1" :
+ ret;
+ }
+ // Opera sometimes will give the wrong display answer, this fixes it, see #2037
+ if ( jQuery.browser.opera && name == "display" ) {
+ var save = elem.style.outline;
+ elem.style.outline = "0 solid black";
+ elem.style.outline = save;
+ }
+
+ // Make sure we're using the right name for getting the float value
+ if ( name.match( /float/i ) )
+ name = styleFloat;
+
+ if ( !force && elem.style && elem.style[ name ] )
+ ret = elem.style[ name ];
+
+ else if ( document.defaultView && document.defaultView.getComputedStyle ) {
+
+ // Only "float" is needed here
+ if ( name.match( /float/i ) )
+ name = "float";
+
+ name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
+
+ var getComputedStyle = document.defaultView.getComputedStyle( elem, null );
+
+ if ( getComputedStyle && !color( elem ) )
+ ret = getComputedStyle.getPropertyValue( name );
+
+ // If the element isn't reporting its values properly in Safari
+ // then some display: none elements are involved
+ else {
+ var swap = [], stack = [];
+
+ // Locate all of the parent display: none elements
+ for ( var a = elem; a && color(a); a = a.parentNode )
+ stack.unshift(a);
+
+ // Go through and make them visible, but in reverse
+ // (It would be better if we knew the exact display type that they had)
+ for ( var i = 0; i < stack.length; i++ )
+ if ( color( stack[ i ] ) ) {
+ swap[ i ] = stack[ i ].style.display;
+ stack[ i ].style.display = "block";
+ }
+
+ // Since we flip the display style, we have to handle that
+ // one special, otherwise get the value
+ ret = name == "display" && swap[ stack.length - 1 ] != null ?
+ "none" :
+ ( getComputedStyle && getComputedStyle.getPropertyValue( name ) ) || "";
+
+ // Finally, revert the display styles back
+ for ( var i = 0; i < swap.length; i++ )
+ if ( swap[ i ] != null )
+ stack[ i ].style.display = swap[ i ];
+ }
+
+ // We should always get a number back from opacity
+ if ( name == "opacity" && ret == "" )
+ ret = "1";
+
+ } else if ( elem.currentStyle ) {
+ var camelCase = name.replace(/\-(\w)/g, function(all, letter){
+ return letter.toUpperCase();
+ });
+
+ ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
+ // Remember the original values
+ var style = elem.style.left, runtimeStyle = elem.runtimeStyle.left;
+
+ // Put in the new values to get a computed value out
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ elem.style.left = ret || 0;
+ ret = elem.style.pixelLeft + "px";
+
+ // Revert the changed values
+ elem.style.left = style;
+ elem.runtimeStyle.left = runtimeStyle;
+ }
+ }
+
+ return ret;
+ },
+
+ clean: function( elems, context ) {
+ var ret = [];
+ context = context || document;
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if (typeof context.createElement == 'undefined')
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+
+ jQuery.each(elems, function(i, elem){
+ if ( !elem )
+ return;
+
+ if ( elem.constructor == Number )
+ elem = elem.toString();
+
+ // Convert html string into DOM nodes
+ if ( typeof elem == "string" ) {
+ // Fix "XHTML"-style tags in all browsers
+ elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
+ return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
+ all :
+ front + "></" + tag + ">";
+ });
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
+
+ var wrap =
+ // option or optgroup
+ !tags.indexOf("<opt") &&
+ [ 1, "<select multiple='multiple'>", "</select>" ] ||
+
+ !tags.indexOf("<leg") &&
+ [ 1, "<fieldset>", "</fieldset>" ] ||
+
+ tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
+ [ 1, "<table>", "</table>" ] ||
+
+ !tags.indexOf("<tr") &&
+ [ 2, "<table><tbody>", "</tbody></table>" ] ||
+
+ // <thead> matched above
+ (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
+ [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
+
+ !tags.indexOf("<col") &&
+ [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
+
+ // IE can't serialize <link> and <script> tags normally
+ jQuery.browser.msie &&
+ [ 1, "div<div>", "</div>" ] ||
+
+ [ 0, "", "" ];
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + elem + wrap[2];
+
+ // Move to the right depth
+ while ( wrap[0]-- )
+ div = div.lastChild;
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( jQuery.browser.msie ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
+ div.firstChild && div.firstChild.childNodes :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
+ div.childNodes :
+ [];
+
+ for ( var j = tbody.length - 1; j >= 0 ; --j )
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( /^\s/.test( elem ) )
+ div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
+
+ }
+
+ elem = jQuery.makeArray( div.childNodes );
+ }
+
+ if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
+ return;
+
+ if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
+ ret.push( elem );
+
+ else
+ ret = jQuery.merge( ret, elem );
+
+ });
+
+ return ret;
+ },
+
+ attr: function( elem, name, value ) {
+ // don't set attributes on text and comment nodes
+ if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
+ return undefined;
+
+ var fix = jQuery.isXMLDoc( elem ) ?
+ {} :
+ jQuery.props;
+
+ // Safari mis-reports the default selected property of a hidden option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name == "selected" && jQuery.browser.safari )
+ elem.parentNode.selectedIndex;
+
+ // Certain attributes only work when accessed via the old DOM 0 way
+ if ( fix[ name ] ) {
+ if ( value != undefined )
+ elem[ fix[ name ] ] = value;
+
+ return elem[ fix[ name ] ];
+
+ } else if ( jQuery.browser.msie && name == "style" )
+ return jQuery.attr( elem.style, "cssText", value );
+
+ else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName( elem, "form" ) && (name == "action" || name == "method") )
+ return elem.getAttributeNode( name ).nodeValue;
+
+ // IE elem.getAttribute passes even for style
+ else if ( elem.tagName ) {
+
+ if ( value != undefined ) {
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
+ throw "type property can't be changed";
+
+ // convert the value to a string (all browsers do this but IE) see #1070
+ elem.setAttribute( name, "" + value );
+ }
+
+ if ( jQuery.browser.msie && /href|src/.test( name ) && !jQuery.isXMLDoc( elem ) )
+ return elem.getAttribute( name, 2 );
+
+ return elem.getAttribute( name );
+
+ // elem is actually elem.style ... set the style
+ } else {
+ // IE actually uses filters for opacity
+ if ( name == "opacity" && jQuery.browser.msie ) {
+ if ( value != undefined ) {
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ elem.zoom = 1;
+
+ // Set the alpha filter to set the opacity
+ elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
+ (parseFloat( value ).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
+ }
+
+ return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
+ (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() :
+ "";
+ }
+
+ name = name.replace(/-([a-z])/ig, function(all, letter){
+ return letter.toUpperCase();
+ });
+
+ if ( value != undefined )
+ elem[ name ] = value;
+
+ return elem[ name ];
+ }
+ },
+
+ trim: function( text ) {
+ return (text || "").replace( /^\s+|\s+$/g, "" );
+ },
+
+ makeArray: function( array ) {
+ var ret = [];
+
+ // Need to use typeof to fight Safari childNodes crashes
+ if ( typeof array != "array" )
+ for ( var i = 0, length = array.length; i < length; i++ )
+ ret.push( array[ i ] );
+ else
+ ret = array.slice( 0 );
+
+ return ret;
+ },
+
+ inArray: function( elem, array ) {
+ for ( var i = 0, length = array.length; i < length; i++ )
+ if ( array[ i ] == elem )
+ return i;
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ // We have to loop this way because IE & Opera overwrite the length
+ // expando of getElementsByTagName
+
+ // Also, we need to make sure that the correct elements are being returned
+ // (IE returns comment nodes in a '*' query)
+ if ( jQuery.browser.msie ) {
+ for ( var i = 0; second[ i ]; i++ )
+ if ( second[ i ].nodeType != 8 )
+ first.push( second[ i ] );
+
+ } else
+ for ( var i = 0; second[ i ]; i++ )
+ first.push( second[ i ] );
+
+ return first;
+ },
+
+ unique: function( array ) {
+ var ret = [], done = {};
+
+ try {
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ var id = jQuery.data( array[ i ] );
+
+ if ( !done[ id ] ) {
+ done[ id ] = true;
+ ret.push( array[ i ] );
+ }
+ }
+
+ } catch( e ) {
+ ret = array;
+ }
+
+ return ret;
+ },
+
+ grep: function( elems, callback, inv ) {
+ var ret = [];
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ )
+ if ( !inv && callback( elems[ i ], i ) || inv && !callback( elems[ i ], i ) )
+ ret.push( elems[ i ] );
+
+ return ret;
+ },
+
+ map: function( elems, callback ) {
+ var ret = [];
+
+ // Go through the array, translating each of the items to their
+ // new value (or values).
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ var value = callback( elems[ i ], i );
+
+ if ( value !== null && value != undefined ) {
+ if ( value.constructor != Array )
+ value = [ value ];
+
+ ret = ret.concat( value );
+ }
+ }
+
+ return ret;
+ }
+});
+
+var userAgent = navigator.userAgent.toLowerCase();
+
+// Figure out what browser is being used
+jQuery.browser = {
+ version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
+ safari: /webkit/.test( userAgent ),
+ opera: /opera/.test( userAgent ),
+ msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
+ mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
+};
+
+var styleFloat = jQuery.browser.msie ?
+ "styleFloat" :
+ "cssFloat";
+
+jQuery.extend({
+ // Check to see if the W3C box model is being used
+ boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
+
+ props: {
+ "for": "htmlFor",
+ "class": "className",
+ "float": styleFloat,
+ cssFloat: styleFloat,
+ styleFloat: styleFloat,
+ innerHTML: "innerHTML",
+ className: "className",
+ value: "value",
+ disabled: "disabled",
+ checked: "checked",
+ readonly: "readOnly",
+ selected: "selected",
+ maxlength: "maxLength",
+ selectedIndex: "selectedIndex",
+ defaultValue: "defaultValue",
+ tagName: "tagName",
+ nodeName: "nodeName"
+ }
+});
+
+jQuery.each({
+ parent: function(elem){return elem.parentNode;},
+ parents: function(elem){return jQuery.dir(elem,"parentNode");},
+ next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
+ prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
+ nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
+ prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
+ siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
+ children: function(elem){return jQuery.sibling(elem.firstChild);},
+ contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
+}, function(name, fn){
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = jQuery.map( this, fn );
+
+ if ( selector && typeof selector == "string" )
+ ret = jQuery.multiFilter( selector, ret );
+
+ return this.pushStack( jQuery.unique( ret ) );
+ };
+});
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function(name, original){
+ jQuery.fn[ name ] = function() {
+ var args = arguments;
+
+ return this.each(function(){
+ for ( var i = 0, length = args.length; i < length; i++ )
+ jQuery( args[ i ] )[ original ]( this );
+ });
+ };
+});
+
+jQuery.each({
+ removeAttr: function( name ) {
+ jQuery.attr( this, name, "" );
+ if (this.nodeType == 1)
+ this.removeAttribute( name );
+ },
+
+ addClass: function( classNames ) {
+ jQuery.className.add( this, classNames );
+ },
+
+ removeClass: function( classNames ) {
+ jQuery.className.remove( this, classNames );
+ },
+
+ toggleClass: function( classNames ) {
+ jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
+ },
+
+ remove: function( selector ) {
+ if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
+ // Prevent memory leaks
+ jQuery( "*", this ).add(this).each(function(){
+ jQuery.event.remove(this);
+ jQuery.removeData(this);
+ });
+ if (this.parentNode)
+ this.parentNode.removeChild( this );
+ }
+ },
+
+ empty: function() {
+ // Remove element nodes and prevent memory leaks
+ jQuery( ">*", this ).remove();
+
+ // Remove any remaining nodes
+ while ( this.firstChild )
+ this.removeChild( this.firstChild );
+ }
+}, function(name, fn){
+ jQuery.fn[ name ] = function(){
+ return this.each( fn, arguments );
+ };
+});
+
+jQuery.each([ "Height", "Width" ], function(i, name){
+ var type = name.toLowerCase();
+
+ jQuery.fn[ type ] = function( size ) {
+ // Get window width or height
+ return this[0] == window ?
+ // Opera reports document.body.client[Width/Height] properly in both quirks and standards
+ jQuery.browser.opera && document.body[ "client" + name ] ||
+
+ // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
+ jQuery.browser.safari && window[ "inner" + name ] ||
+
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
+
+ // Get document width or height
+ this[0] == document ?
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ Math.max(
+ Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
+ Math.max(document.body["offset" + name], document.documentElement["offset" + name])
+ ) :
+
+ // Get or set width or height on the element
+ size == undefined ?
+ // Get width or height on the element
+ (this.length ? jQuery.css( this[0], type ) : null) :
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ this.css( type, size.constructor == String ? size : size + "px" );
+ };
+});
+
+var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
+ "(?:[\\w*_-]|\\\\.)" :
+ "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
+ quickChild = new RegExp("^>\\s*(" + chars + "+)"),
+ quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
+ quickClass = new RegExp("^([#.]?)(" + chars + "*)");
+
+jQuery.extend({
+ expr: {
+ "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
+ "#": function(a,i,m){return a.getAttribute("id")==m[2];},
+ ":": {
+ // Position Checks
+ lt: function(a,i,m){return i<m[3]-0;},
+ gt: function(a,i,m){return i>m[3]-0;},
+ nth: function(a,i,m){return m[3]-0==i;},
+ eq: function(a,i,m){return m[3]-0==i;},
+ first: function(a,i){return i==0;},
+ last: function(a,i,m,r){return i==r.length-1;},
+ even: function(a,i){return i%2==0;},
+ odd: function(a,i){return i%2;},
+
+ // Child Checks
+ "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
+ "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
+ "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
+
+ // Parent Checks
+ parent: function(a){return a.firstChild;},
+ empty: function(a){return !a.firstChild;},
+
+ // Text Check
+ contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
+
+ // Visibility
+ visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
+ hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
+
+ // Form attributes
+ enabled: function(a){return !a.disabled;},
+ disabled: function(a){return a.disabled;},
+ checked: function(a){return a.checked;},
+ selected: function(a){return a.selected||jQuery.attr(a,"selected");},
+
+ // Form elements
+ text: function(a){return "text"==a.type;},
+ radio: function(a){return "radio"==a.type;},
+ checkbox: function(a){return "checkbox"==a.type;},
+ file: function(a){return "file"==a.type;},
+ password: function(a){return "password"==a.type;},
+ submit: function(a){return "submit"==a.type;},
+ image: function(a){return "image"==a.type;},
+ reset: function(a){return "reset"==a.type;},
+ button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
+ input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},
+
+ // :has()
+ has: function(a,i,m){return jQuery.find(m[3],a).length;},
+
+ // :header
+ header: function(a){return /h\d/i.test(a.nodeName);},
+
+ // :animated
+ animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
+ }
+ },
+
+ // The regular expressions that power the parsing engine
+ parse: [
+ // Match: [@value='test'], [@foo]
+ /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
+
+ // Match: :contains('foo')
+ /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
+
+ // Match: :even, :last-chlid, #id, .class
+ new RegExp("^([:.#]*)(" + chars + "+)")
+ ],
+
+ multiFilter: function( expr, elems, not ) {
+ var old, cur = [];
+
+ while ( expr && expr != old ) {
+ old = expr;
+ var f = jQuery.filter( expr, elems, not );
+ expr = f.t.replace(/^\s*,\s*/, "" );
+ cur = not ? elems = f.r : jQuery.merge( cur, f.r );
+ }
+
+ return cur;
+ },
+
+ find: function( t, context ) {
+ // Quickly handle non-string expressions
+ if ( typeof t != "string" )
+ return [ t ];
+
+ // check to make sure context is a DOM element or a document
+ if ( context && context.nodeType != 1 && context.nodeType != 9)
+ return [ ];
+
+ // Set the correct context (if none is provided)
+ context = context || document;
+
+ // Initialize the search
+ var ret = [context], done = [], last, nodeName;
+
+ // Continue while a selector expression exists, and while
+ // we're no longer looping upon ourselves
+ while ( t && last != t ) {
+ var r = [];
+ last = t;
+
+ t = jQuery.trim(t);
+
+ var foundToken = false;
+
+ // An attempt at speeding up child selectors that
+ // point to a specific element tag
+ var re = quickChild;
+ var m = re.exec(t);
+
+ if ( m ) {
+ nodeName = m[1].toUpperCase();
+
+ // Perform our own iteration and filter
+ for ( var i = 0; ret[i]; i++ )
+ for ( var c = ret[i].firstChild; c; c = c.nextSibling )
+ if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
+ r.push( c );
+
+ ret = r;
+ t = t.replace( re, "" );
+ if ( t.indexOf(" ") == 0 ) continue;
+ foundToken = true;
+ } else {
+ re = /^([>+~])\s*(\w*)/i;
+
+ if ( (m = re.exec(t)) != null ) {
+ r = [];
+
+ var merge = {};
+ nodeName = m[2].toUpperCase();
+ m = m[1];
+
+ for ( var j = 0, rl = ret.length; j < rl; j++ ) {
+ var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
+ for ( ; n; n = n.nextSibling )
+ if ( n.nodeType == 1 ) {
+ var id = jQuery.data(n);
+
+ if ( m == "~" && merge[id] ) break;
+
+ if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
+ if ( m == "~" ) merge[id] = true;
+ r.push( n );
+ }
+
+ if ( m == "+" ) break;
+ }
+ }
+
+ ret = r;
+
+ // And remove the token
+ t = jQuery.trim( t.replace( re, "" ) );
+ foundToken = true;
+ }
+ }
+
+ // See if there's still an expression, and that we haven't already
+ // matched a token
+ if ( t && !foundToken ) {
+ // Handle multiple expressions
+ if ( !t.indexOf(",") ) {
+ // Clean the result set
+ if ( context == ret[0] ) ret.shift();
+
+ // Merge the result sets
+ done = jQuery.merge( done, ret );
+
+ // Reset the context
+ r = ret = [context];
+
+ // Touch up the selector string
+ t = " " + t.substr(1,t.length);
+
+ } else {
+ // Optimize for the case nodeName#idName
+ var re2 = quickID;
+ var m = re2.exec(t);
+
+ // Re-organize the results, so that they're consistent
+ if ( m ) {
+ m = [ 0, m[2], m[3], m[1] ];
+
+ } else {
+ // Otherwise, do a traditional filter check for
+ // ID, class, and element selectors
+ re2 = quickClass;
+ m = re2.exec(t);
+ }
+
+ m[2] = m[2].replace(/\\/g, "");
+
+ var elem = ret[ret.length-1];
+
+ // Try to do a global search by ID, where we can
+ if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
+ // Optimization for HTML document case
+ var oid = elem.getElementById(m[2]);
+
+ // Do a quick check for the existence of the actual ID attribute
+ // to avoid selecting by the name attribute in IE
+ // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
+ if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
+ oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
+
+ // Do a quick check for node name (where applicable) so
+ // that div#foo searches will be really fast
+ ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
+ } else {
+ // We need to find all descendant elements
+ for ( var i = 0; ret[i]; i++ ) {
+ // Grab the tag name being searched for
+ var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
+
+ // Handle IE7 being really dumb about <object>s
+ if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
+ tag = "param";
+
+ r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
+ }
+
+ // It's faster to filter by class and be done with it
+ if ( m[1] == "." )
+ r = jQuery.classFilter( r, m[2] );
+
+ // Same with ID filtering
+ if ( m[1] == "#" ) {
+ var tmp = [];
+
+ // Try to find the element with the ID
+ for ( var i = 0; r[i]; i++ )
+ if ( r[i].getAttribute("id") == m[2] ) {
+ tmp = [ r[i] ];
+ break;
+ }
+
+ r = tmp;
+ }
+
+ ret = r;
+ }
+
+ t = t.replace( re2, "" );
+ }
+
+ }
+
+ // If a selector string still exists
+ if ( t ) {
+ // Attempt to filter it
+ var val = jQuery.filter(t,r);
+ ret = r = val.r;
+ t = jQuery.trim(val.t);
+ }
+ }
+
+ // An error occurred with the selector;
+ // just return an empty set instead
+ if ( t )
+ ret = [];
+
+ // Remove the root context
+ if ( ret && context == ret[0] )
+ ret.shift();
+
+ // And combine the results
+ done = jQuery.merge( done, ret );
+
+ return done;
+ },
+
+ classFilter: function(r,m,not){
+ m = " " + m + " ";
+ var tmp = [];
+ for ( var i = 0; r[i]; i++ ) {
+ var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
+ if ( !not && pass || not && !pass )
+ tmp.push( r[i] );
+ }
+ return tmp;
+ },
+
+ filter: function(t,r,not) {
+ var last;
+
+ // Look for common filter expressions
+ while ( t && t != last ) {
+ last = t;
+
+ var p = jQuery.parse, m;
+
+ for ( var i = 0; p[i]; i++ ) {
+ m = p[i].exec( t );
+
+ if ( m ) {
+ // Remove what we just matched
+ t = t.substring( m[0].length );
+
+ m[2] = m[2].replace(/\\/g, "");
+ break;
+ }
+ }
+
+ if ( !m )
+ break;
+
+ // :not() is a special case that can be optimized by
+ // keeping it out of the expression list
+ if ( m[1] == ":" && m[2] == "not" )
+ // optimize if only one selector found (most common case)
+ r = isSimple.test( m[3] ) ?
+ jQuery.filter(m[3], r, true).r :
+ jQuery( r ).not( m[3] );
+
+ // We can get a big speed boost by filtering by class here
+ else if ( m[1] == "." )
+ r = jQuery.classFilter(r, m[2], not);
+
+ else if ( m[1] == "[" ) {
+ var tmp = [], type = m[3];
+
+ for ( var i = 0, rl = r.length; i < rl; i++ ) {
+ var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
+
+ if ( z == null || /href|src|selected/.test(m[2]) )
+ z = jQuery.attr(a,m[2]) || '';
+
+ if ( (type == "" && !!z ||
+ type == "=" && z == m[5] ||
+ type == "!=" && z != m[5] ||
+ type == "^=" && z && !z.indexOf(m[5]) ||
+ type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
+ (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
+ tmp.push( a );
+ }
+
+ r = tmp;
+
+ // We can get a speed boost by handling nth-child here
+ } else if ( m[1] == ":" && m[2] == "nth-child" ) {
+ var merge = {}, tmp = [],
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+ m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
+ !/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
+ // calculate the numbers (first)n+(last) including if they are negative
+ first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
+
+ // loop through all the elements left in the jQuery object
+ for ( var i = 0, rl = r.length; i < rl; i++ ) {
+ var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
+
+ if ( !merge[id] ) {
+ var c = 1;
+
+ for ( var n = parentNode.firstChild; n; n = n.nextSibling )
+ if ( n.nodeType == 1 )
+ n.nodeIndex = c++;
+
+ merge[id] = true;
+ }
+
+ var add = false;
+
+ if ( first == 0 ) {
+ if ( node.nodeIndex == last )
+ add = true;
+ } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
+ add = true;
+
+ if ( add ^ not )
+ tmp.push( node );
+ }
+
+ r = tmp;
+
+ // Otherwise, find the expression to execute
+ } else {
+ var fn = jQuery.expr[ m[1] ];
+ if ( typeof fn == "object" )
+ fn = fn[ m[2] ];
+
+ if ( typeof fn == "string" )
+ fn = eval("false||function(a,i){return " + fn + ";}");
+
+ // Execute it against the current filter
+ r = jQuery.grep( r, function(elem, i){
+ return fn(elem, i, m, r);
+ }, not );
+ }
+ }
+
+ // Return an array of filtered elements (r)
+ // and the modified expression string (t)
+ return { r: r, t: t };
+ },
+
+ dir: function( elem, dir ){
+ var matched = [];
+ var cur = elem[dir];
+ while ( cur && cur != document ) {
+ if ( cur.nodeType == 1 )
+ matched.push( cur );
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ nth: function(cur,result,dir,elem){
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] )
+ if ( cur.nodeType == 1 && ++num == result )
+ break;
+
+ return cur;
+ },
+
+ sibling: function( n, elem ) {
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType == 1 && (!elem || n != elem) )
+ r.push( n );
+ }
+
+ return r;
+ }
+});
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code orignated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function(elem, types, handler, data) {
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return;
+
+ // For whatever reason, IE has trouble passing the window object
+ // around, causing it to be cloned in the process
+ if ( jQuery.browser.msie && elem.setInterval != undefined )
+ elem = window;
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid )
+ handler.guid = this.guid++;
+
+ // if data is passed, bind to handler
+ if( data != undefined ) {
+ // Create temporary function pointer to original handler
+ var fn = handler;
+
+ // Create unique handler function, wrapped around original handler
+ handler = function() {
+ // Pass arguments and context to original handler
+ return fn.apply(this, arguments);
+ };
+
+ // Store data in unique handler
+ handler.data = data;
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ handler.guid = fn.guid;
+ }
+
+ // Init the element's event structure
+ var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
+ handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
+ // returned undefined or false
+ var val;
+
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ if ( typeof jQuery == "undefined" || jQuery.event.triggered )
+ return val;
+
+ val = jQuery.event.handle.apply(arguments.callee.elem, arguments);
+
+ return val;
+ });
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native
+ // event in IE.
+ handle.elem = elem;
+
+ // Handle multiple events seperated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ jQuery.each(types.split(/\s+/), function(index, type) {
+ // Namespaced event handlers
+ var parts = type.split(".");
+ type = parts[0];
+ handler.type = parts[1];
+
+ // Get the current list of functions bound to this event
+ var handlers = events[type];
+
+ // Init the event handler queue
+ if (!handlers) {
+ handlers = events[type] = {};
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
+ // Bind the global event handler to the element
+ if (elem.addEventListener)
+ elem.addEventListener(type, handle, false);
+ else if (elem.attachEvent)
+ elem.attachEvent("on" + type, handle);
+ }
+ }
+
+ // Add the function to the element's handler list
+ handlers[handler.guid] = handler;
+
+ // Keep track of which events have been used, for global triggering
+ jQuery.event.global[type] = true;
+ });
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ guid: 1,
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function(elem, types, handler) {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return;
+
+ var events = jQuery.data(elem, "events"), ret, index;
+
+ if ( events ) {
+ // Unbind all events for the element
+ if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
+ for ( var type in events )
+ this.remove( elem, type + (types || "") );
+ else {
+ // types is actually an event object here
+ if ( types.type ) {
+ handler = types.handler;
+ types = types.type;
+ }
+
+ // Handle multiple events seperated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ jQuery.each(types.split(/\s+/), function(index, type){
+ // Namespaced event handlers
+ var parts = type.split(".");
+ type = parts[0];
+
+ if ( events[type] ) {
+ // remove the given handler for the given type
+ if ( handler )
+ delete events[type][handler.guid];
+
+ // remove all handlers for the given type
+ else
+ for ( handler in events[type] )
+ // Handle the removal of namespaced events
+ if ( !parts[1] || events[type][handler].type == parts[1] )
+ delete events[type][handler];
+
+ // remove generic event handler if no more handlers exist
+ for ( ret in events[type] ) break;
+ if ( !ret ) {
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
+ if (elem.removeEventListener)
+ elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
+ else if (elem.detachEvent)
+ elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
+ }
+ ret = null;
+ delete events[type];
+ }
+ }
+ });
+ }
+
+ // Remove the expando if it's no longer used
+ for ( ret in events ) break;
+ if ( !ret ) {
+ var handle = jQuery.data( elem, "handle" );
+ if ( handle ) handle.elem = null;
+ jQuery.removeData( elem, "events" );
+ jQuery.removeData( elem, "handle" );
+ }
+ }
+ },
+
+ trigger: function(type, data, elem, donative, extra) {
+ // Clone the incoming data, if any
+ data = jQuery.makeArray(data || []);
+
+ if ( type.indexOf("!") >= 0 ) {
+ type = type.slice(0, -1);
+ var exclusive = true;
+ }
+
+ // Handle a global trigger
+ if ( !elem ) {
+ // Only trigger if we've ever bound an event for it
+ if ( this.global[type] )
+ jQuery("*").add([window, document]).trigger(type, data);
+
+ // Handle triggering a single element
+ } else {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return undefined;
+
+ var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
+ // Check to see if we need to provide a fake event, or not
+ event = !data[0] || !data[0].preventDefault;
+
+ // Pass along a fake event
+ if ( event )
+ data.unshift( this.fix({ type: type, target: elem }) );
+
+ // Enforce the right trigger type
+ data[0].type = type;
+ if ( exclusive )
+ data[0].exclusive = true;
+
+ // Trigger the event
+ if ( jQuery.isFunction( jQuery.data(elem, "handle") ) )
+ val = jQuery.data(elem, "handle").apply( elem, data );
+
+ // Handle triggering native .onfoo handlers
+ if ( !fn && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
+ val = false;
+
+ // Extra functions don't get the custom event object
+ if ( event )
+ data.shift();
+
+ // Handle triggering of extra function
+ if ( extra && jQuery.isFunction( extra ) ) {
+ // call the extra function and tack the current return value on the end for possible inspection
+ ret = extra.apply( elem, val == null ? data : data.concat( val ) );
+ // if anything is returned, give it precedence and have it overwrite the previous value
+ if (ret !== undefined)
+ val = ret;
+ }
+
+ // Trigger the native events (except for clicks on links)
+ if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
+ this.triggered = true;
+ try {
+ elem[ type ]();
+ // prevent IE from throwing an error for some hidden elements
+ } catch (e) {}
+ }
+
+ this.triggered = false;
+ }
+
+ return val;
+ },
+
+ handle: function(event) {
+ // returned undefined or false
+ var val;
+
+ // Empty object is for triggered events with no data
+ event = jQuery.event.fix( event || window.event || {} );
+
+ // Namespaced event handlers
+ var parts = event.type.split(".");
+ event.type = parts[0];
+
+ var handlers = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 );
+ args.unshift( event );
+
+ for ( var j in handlers ) {
+ var handler = handlers[j];
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ args[0].handler = handler;
+ args[0].data = handler.data;
+
+ // Filter the functions by class
+ if ( !parts[1] && !event.exclusive || handler.type == parts[1] ) {
+ var ret = handler.apply( this, args );
+
+ if ( val !== false )
+ val = ret;
+
+ if ( ret === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }
+
+ // Clean up added properties in IE to prevent memory leak
+ if (jQuery.browser.msie)
+ event.target = event.preventDefault = event.stopPropagation =
+ event.handler = event.data = null;
+
+ return val;
+ },
+
+ fix: function(event) {
+ // store a copy of the original event object
+ // and clone to set read-only properties
+ var originalEvent = event;
+ event = jQuery.extend({}, originalEvent);
+
+ // add preventDefault and stopPropagation since
+ // they will not work on the clone
+ event.preventDefault = function() {
+ // if preventDefault exists run it on the original event
+ if (originalEvent.preventDefault)
+ originalEvent.preventDefault();
+ // otherwise set the returnValue property of the original event to false (IE)
+ originalEvent.returnValue = false;
+ };
+ event.stopPropagation = function() {
+ // if stopPropagation exists run it on the original event
+ if (originalEvent.stopPropagation)
+ originalEvent.stopPropagation();
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ originalEvent.cancelBubble = true;
+ };
+
+ // Fix target property, if necessary
+ if ( !event.target )
+ event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+
+ // check if target is a textnode (safari)
+ if ( event.target.nodeType == 3 )
+ event.target = originalEvent.target.parentNode;
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement )
+ event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var doc = document.documentElement, body = document.body;
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
+ }
+
+ // Add which for key events
+ if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
+ event.which = event.charCode || event.keyCode;
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey )
+ event.metaKey = event.ctrlKey;
+
+ // Add which for click: 1 == left; 2 == middle; 3 == right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button )
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+
+ return event;
+ },
+
+ special: {
+ ready: {
+ setup: function() {
+ // Make sure the ready event is setup
+ bindReady();
+ return;
+ },
+
+ teardown: function() { return; }
+ },
+
+ mouseenter: {
+ setup: function() {
+ if ( jQuery.browser.msie ) return false;
+ jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
+ return true;
+ },
+
+ teardown: function() {
+ if ( jQuery.browser.msie ) return false;
+ jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
+ return true;
+ },
+
+ handler: function(event) {
+ // If we actually just moused on to a sub-element, ignore it
+ if ( withinElement(event, this) ) return true;
+ // Execute the right handlers by setting the event type to mouseenter
+ arguments[0].type = "mouseenter";
+ return jQuery.event.handle.apply(this, arguments);
+ }
+ },
+
+ mouseleave: {
+ setup: function() {
+ if ( jQuery.browser.msie ) return false;
+ jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
+ return true;
+ },
+
+ teardown: function() {
+ if ( jQuery.browser.msie ) return false;
+ jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
+ return true;
+ },
+
+ handler: function(event) {
+ // If we actually just moused on to a sub-element, ignore it
+ if ( withinElement(event, this) ) return true;
+ // Execute the right handlers by setting the event type to mouseleave
+ arguments[0].type = "mouseleave";
+ return jQuery.event.handle.apply(this, arguments);
+ }
+ }
+ }
+};
+
+jQuery.fn.extend({
+ bind: function( type, data, fn ) {
+ return type == "unload" ? this.one(type, data, fn) : this.each(function(){
+ jQuery.event.add( this, type, fn || data, fn && data );
+ });
+ },
+
+ one: function( type, data, fn ) {
+ return this.each(function(){
+ jQuery.event.add( this, type, function(event) {
+ jQuery(this).unbind(event);
+ return (fn || data).apply( this, arguments);
+ }, fn && data);
+ });
+ },
+
+ unbind: function( type, fn ) {
+ return this.each(function(){
+ jQuery.event.remove( this, type, fn );
+ });
+ },
+
+ trigger: function( type, data, fn ) {
+ return this.each(function(){
+ jQuery.event.trigger( type, data, this, true, fn );
+ });
+ },
+
+ triggerHandler: function( type, data, fn ) {
+ if ( this[0] )
+ return jQuery.event.trigger( type, data, this[0], false, fn );
+ return undefined;
+ },
+
+ toggle: function() {
+ // Save reference to arguments for access in closure
+ var args = arguments;
+
+ return this.click(function(event) {
+ // Figure out which function to execute
+ this.lastToggle = 0 == this.lastToggle ? 1 : 0;
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[this.lastToggle].apply( this, arguments ) || false;
+ });
+ },
+
+ hover: function(fnOver, fnOut) {
+ return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
+ },
+
+ ready: function(fn) {
+ // Attach the listeners
+ bindReady();
+
+ // If the DOM is already ready
+ if ( jQuery.isReady )
+ // Execute the function immediately
+ fn.call( document, jQuery );
+
+ // Otherwise, remember the function for later
+ else
+ // Add the function to the wait list
+ jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
+
+ return this;
+ }
+});
+
+jQuery.extend({
+ isReady: false,
+ readyList: [],
+ // Handle when the DOM is ready
+ ready: function() {
+ // Make sure that the DOM is not already loaded
+ if ( !jQuery.isReady ) {
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If there are functions bound, to execute
+ if ( jQuery.readyList ) {
+ // Execute all of them
+ jQuery.each( jQuery.readyList, function(){
+ this.apply( document );
+ });
+
+ // Reset the list of functions
+ jQuery.readyList = null;
+ }
+
+ // Trigger any bound ready events
+ jQuery(document).triggerHandler("ready");
+ }
+ }
+});
+
+var readyBound = false;
+
+function bindReady(){
+ if ( readyBound ) return;
+ readyBound = true;
+
+ // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
+ if ( document.addEventListener && !jQuery.browser.opera)
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
+
+ // If IE is used and is not in a frame
+ // Continually check to see if the document is ready
+ if ( jQuery.browser.msie && window == top ) (function(){
+ if (jQuery.isReady) return;
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch( error ) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+ // and execute any waiting functions
+ jQuery.ready();
+ })();
+
+ if ( jQuery.browser.opera )
+ document.addEventListener( "DOMContentLoaded", function () {
+ if (jQuery.isReady) return;
+ for (var i = 0; i < document.styleSheets.length; i++)
+ if (document.styleSheets[i].disabled) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+ // and execute any waiting functions
+ jQuery.ready();
+ }, false);
+
+ if ( jQuery.browser.safari ) {
+ var numStyles;
+ (function(){
+ if (jQuery.isReady) return;
+ if ( document.readyState != "loaded" && document.readyState != "complete" ) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+ if ( numStyles === undefined )
+ numStyles = jQuery("style, link[rel=stylesheet]").length;
+ if ( document.styleSheets.length != numStyles ) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+ // and execute any waiting functions
+ jQuery.ready();
+ })();
+ }
+
+ // A fallback to window.onload, that will always work
+ jQuery.event.add( window, "load", jQuery.ready );
+}
+
+jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
+ "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
+ "submit,keydown,keypress,keyup,error").split(","), function(i, name){
+
+ // Handle event binding
+ jQuery.fn[name] = function(fn){
+ return fn ? this.bind(name, fn) : this.trigger(name);
+ };
+});
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function(event, elem) {
+ // Check if mouse(over|out) are still within the same parent element
+ var parent = event.relatedTarget;
+ // Traverse up the tree
+ while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
+ // Return true if we actually just moused on to a sub-element
+ return parent == elem;
+};
+
+// Prevent memory leaks in IE
+// And prevent errors on refresh with events like mouseover in other browsers
+// Window isn't included so as not to unbind existing unload events
+jQuery(window).bind("unload", function() {
+ jQuery("*").add(document).unbind();
+});
+jQuery.fn.extend({
+ load: function( url, params, callback ) {
+ if ( jQuery.isFunction( url ) )
+ return this.bind("load", url);
+
+ var off = url.indexOf(" ");
+ if ( off >= 0 ) {
+ var selector = url.slice(off, url.length);
+ url = url.slice(0, off);
+ }
+
+ callback = callback || function(){};
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params )
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = null;
+
+ // Otherwise, build a param string
+ } else {
+ params = jQuery.param( params );
+ type = "POST";
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ dataType: "html",
+ data: params,
+ complete: function(res, status){
+ // If successful, inject the HTML into all the matched elements
+ if ( status == "success" || status == "notmodified" )
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div/>")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ res.responseText );
+
+ self.each( callback, [res.responseText, status, res] );
+ }
+ });
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param(this.serializeArray());
+ },
+ serializeArray: function() {
+ return this.map(function(){
+ return jQuery.nodeName(this, "form") ?
+ jQuery.makeArray(this.elements) : this;
+ })
+ .filter(function(){
+ return this.name && !this.disabled &&
+ (this.checked || /select|textarea/i.test(this.nodeName) ||
+ /text|hidden|password/i.test(this.type));
+ })
+ .map(function(i, elem){
+ var val = jQuery(this).val();
+ return val == null ? null :
+ val.constructor == Array ?
+ jQuery.map( val, function(val, i){
+ return {name: elem.name, value: val};
+ }) :
+ {name: elem.name, value: val};
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
+ jQuery.fn[o] = function(f){
+ return this.bind(o, f);
+ };
+});
+
+var jsc = (new Date).getTime();
+
+jQuery.extend({
+ get: function( url, data, callback, type ) {
+ // shift arguments if data argument was ommited
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = null;
+ }
+
+ return jQuery.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get(url, null, callback, "script");
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get(url, data, callback, "json");
+ },
+
+ post: function( url, data, callback, type ) {
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = {};
+ }
+
+ return jQuery.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ ajaxSetup: function( settings ) {
+ jQuery.extend( jQuery.ajaxSettings, settings );
+ },
+
+ ajaxSettings: {
+ global: true,
+ type: "GET",
+ timeout: 0,
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ data: null,
+ username: null,
+ password: null,
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ script: "text/javascript, application/javascript",
+ json: "application/json, text/javascript",
+ text: "text/plain",
+ _default: "*/*"
+ }
+ },
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+
+ ajax: function( s ) {
+ var jsonp, jsre = /=\?(&|$)/g, status, data;
+
+ // Extend the settings, but re-extend 's' so that it can be
+ // checked again later (in the test suite, specifically)
+ s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
+
+ // convert data if not already a string
+ if ( s.data && s.processData && typeof s.data != "string" )
+ s.data = jQuery.param(s.data);
+
+ // Handle JSONP Parameter Callbacks
+ if ( s.dataType == "jsonp" ) {
+ if ( s.type.toLowerCase() == "get" ) {
+ if ( !s.url.match(jsre) )
+ s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+ } else if ( !s.data || !s.data.match(jsre) )
+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+ s.dataType = "json";
+ }
+
+ // Build temporary JSONP function
+ if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
+ jsonp = "jsonp" + jsc++;
+
+ // Replace the =? sequence both in the query string and the data
+ if ( s.data )
+ s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+ s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+ // We need to make sure
+ // that a JSONP style response is executed properly
+ s.dataType = "script";
+
+ // Handle JSONP-style loading
+ window[ jsonp ] = function(tmp){
+ data = tmp;
+ success();
+ complete();
+ // Garbage collect
+ window[ jsonp ] = undefined;
+ try{ delete window[ jsonp ]; } catch(e){}
+ if ( head )
+ head.removeChild( script );
+ };
+ }
+
+ if ( s.dataType == "script" && s.cache == null )
+ s.cache = false;
+
+ if ( s.cache === false && s.type.toLowerCase() == "get" ) {
+ var ts = (new Date()).getTime();
+ // try replacing _= if it is there
+ var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
+ }
+
+ // If data is available, append data to url for get requests
+ if ( s.data && s.type.toLowerCase() == "get" ) {
+ s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
+
+ // IE likes to send both get and post data, prevent this
+ s.data = null;
+ }
+
+ // Watch for a new set of requests
+ if ( s.global && ! jQuery.active++ )
+ jQuery.event.trigger( "ajaxStart" );
+
+ // If we're requesting a remote document
+ // and trying to load JSON or Script with a GET
+ if ( (!s.url.indexOf("http") || !s.url.indexOf("//")) && s.dataType == "script" && s.type.toLowerCase() == "get" ) {
+ var head = document.getElementsByTagName("head")[0];
+ var script = document.createElement("script");
+ script.src = s.url;
+ if (s.scriptCharset)
+ script.charset = s.scriptCharset;
+
+ // Handle Script loading
+ if ( !jsonp ) {
+ var done = false;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function(){
+ if ( !done && (!this.readyState ||
+ this.readyState == "loaded" || this.readyState == "complete") ) {
+ done = true;
+ success();
+ complete();
+ head.removeChild( script );
+ }
+ };
+ }
+
+ head.appendChild(script);
+
+ // We handle everything using the script element injection
+ return undefined;
+ }
+
+ var requestDone = false;
+
+ // Create the request object; Microsoft failed to properly
+ // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
+ var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
+
+ // Open the socket
+ xml.open(s.type, s.url, s.async, s.username, s.password);
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ // Set the correct header, if data is being sent
+ if ( s.data )
+ xml.setRequestHeader("Content-Type", s.contentType);
+
+ // Set the If-Modified-Since header, if ifModified mode.
+ if ( s.ifModified )
+ xml.setRequestHeader("If-Modified-Since",
+ jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
+
+ // Set header so the called script knows that it's an XMLHttpRequest
+ xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+
+ // Set the Accepts header for the server, depending on the dataType
+ xml.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+ s.accepts[ s.dataType ] + ", */*" :
+ s.accepts._default );
+ } catch(e){}
+
+ // Allow custom headers/mimetypes
+ if ( s.beforeSend )
+ s.beforeSend(xml);
+
+ if ( s.global )
+ jQuery.event.trigger("ajaxSend", [xml, s]);
+
+ // Wait for a response to come back
+ var onreadystatechange = function(isTimeout){
+ // The transfer is complete and the data is available, or the request timed out
+ if ( !requestDone && xml && (xml.readyState == 4 || isTimeout == "timeout") ) {
+ requestDone = true;
+
+ // clear poll interval
+ if (ival) {
+ clearInterval(ival);
+ ival = null;
+ }
+
+ status = isTimeout == "timeout" && "timeout" ||
+ !jQuery.httpSuccess( xml ) && "error" ||
+ s.ifModified && jQuery.httpNotModified( xml, s.url ) && "notmodified" ||
+ "success";
+
+ if ( status == "success" ) {
+ // Watch for, and catch, XML document parse errors
+ try {
+ // process the data (runs the xml through httpData regardless of callback)
+ data = jQuery.httpData( xml, s.dataType );
+ } catch(e) {
+ status = "parsererror";
+ }
+ }
+
+ // Make sure that the request was successful or notmodified
+ if ( status == "success" ) {
+ // Cache Last-Modified header, if ifModified mode.
+ var modRes;
+ try {
+ modRes = xml.getResponseHeader("Last-Modified");
+ } catch(e) {} // swallow exception thrown by FF if header is not available
+
+ if ( s.ifModified && modRes )
+ jQuery.lastModified[s.url] = modRes;
+
+ // JSONP handles its own success callback
+ if ( !jsonp )
+ success();
+ } else
+ jQuery.handleError(s, xml, status);
+
+ // Fire the complete handlers
+ complete();
+
+ // Stop memory leaks
+ if ( s.async )
+ xml = null;
+ }
+ };
+
+ if ( s.async ) {
+ // don't attach the handler to the request, just poll it instead
+ var ival = setInterval(onreadystatechange, 13);
+
+ // Timeout checker
+ if ( s.timeout > 0 )
+ setTimeout(function(){
+ // Check to see if the request is still happening
+ if ( xml ) {
+ // Cancel the request
+ xml.abort();
+
+ if( !requestDone )
+ onreadystatechange( "timeout" );
+ }
+ }, s.timeout);
+ }
+
+ // Send the data
+ try {
+ xml.send(s.data);
+ } catch(e) {
+ jQuery.handleError(s, xml, null, e);
+ }
+
+ // firefox 1.5 doesn't fire statechange for sync requests
+ if ( !s.async )
+ onreadystatechange();
+
+ function success(){
+ // If a local callback was specified, fire it and pass it the data
+ if ( s.success )
+ s.success( data, status );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxSuccess", [xml, s] );
+ }
+
+ function complete(){
+ // Process result
+ if ( s.complete )
+ s.complete(xml, status);
+
+ // The request was completed
+ if ( s.global )
+ jQuery.event.trigger( "ajaxComplete", [xml, s] );
+
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ }
+
+ // return XMLHttpRequest to allow aborting the request etc.
+ return xml;
+ },
+
+ handleError: function( s, xml, status, e ) {
+ // If a local callback was specified, fire it
+ if ( s.error ) s.error( xml, status, e );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxError", [xml, s, e] );
+ },
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Determines if an XMLHttpRequest was successful or not
+ httpSuccess: function( r ) {
+ try {
+ // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+ return !r.status && location.protocol == "file:" ||
+ ( r.status >= 200 && r.status < 300 ) || r.status == 304 || r.status == 1223 ||
+ jQuery.browser.safari && r.status == undefined;
+ } catch(e){}
+ return false;
+ },
+
+ // Determines if an XMLHttpRequest returns NotModified
+ httpNotModified: function( xml, url ) {
+ try {
+ var xmlRes = xml.getResponseHeader("Last-Modified");
+
+ // Firefox always returns 200. check Last-Modified date
+ return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
+ jQuery.browser.safari && xml.status == undefined;
+ } catch(e){}
+ return false;
+ },
+
+ httpData: function( r, type ) {
+ var ct = r.getResponseHeader("content-type");
+ var xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0;
+ var data = xml ? r.responseXML : r.responseText;
+
+ if ( xml && data.documentElement.tagName == "parsererror" )
+ throw "parsererror";
+
+ // If the type is "script", eval it in global context
+ if ( type == "script" )
+ jQuery.globalEval( data );
+
+ // Get the JavaScript object, if JSON is used.
+ if ( type == "json" )
+ data = eval("(" + data + ")");
+
+ return data;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a ) {
+ var s = [];
+
+ // If an array was passed in, assume that it is an array
+ // of form elements
+ if ( a.constructor == Array || a.jquery )
+ // Serialize the form elements
+ jQuery.each( a, function(){
+ s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
+ });
+
+ // Otherwise, assume that it's an object of key/value pairs
+ else
+ // Serialize the key/values
+ for ( var j in a )
+ // If the value is an array then the key names need to be repeated
+ if ( a[j] && a[j].constructor == Array )
+ jQuery.each( a[j], function(){
+ s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
+ });
+ else
+ s.push( encodeURIComponent(j) + "=" + encodeURIComponent( a[j] ) );
+
+ // Return the resulting serialization
+ return s.join("&").replace(/%20/g, "+");
+ }
+
+});
+jQuery.fn.extend({
+ show: function(speed,callback){
+ return speed ?
+ this.animate({
+ height: "show", width: "show", opacity: "show"
+ }, speed, callback) :
+
+ this.filter(":hidden").each(function(){
+ this.style.display = this.oldblock || "";
+ if ( jQuery.css(this,"display") == "none" ) {
+ var elem = jQuery("<" + this.tagName + " />").appendTo("body");
+ this.style.display = elem.css("display");
+ // handle an edge condition where css is - div { display:none; } or similar
+ if (this.style.display == "none")
+ this.style.display = "block";
+ elem.remove();
+ }
+ }).end();
+ },
+
+ hide: function(speed,callback){
+ return speed ?
+ this.animate({
+ height: "hide", width: "hide", opacity: "hide"
+ }, speed, callback) :
+
+ this.filter(":visible").each(function(){
+ this.oldblock = this.oldblock || jQuery.css(this,"display");
+ this.style.display = "none";
+ }).end();
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2 ){
+ return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
+ this._toggle( fn, fn2 ) :
+ fn ?
+ this.animate({
+ height: "toggle", width: "toggle", opacity: "toggle"
+ }, fn, fn2) :
+ this.each(function(){
+ jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
+ });
+ },
+
+ slideDown: function(speed,callback){
+ return this.animate({height: "show"}, speed, callback);
+ },
+
+ slideUp: function(speed,callback){
+ return this.animate({height: "hide"}, speed, callback);
+ },
+
+ slideToggle: function(speed, callback){
+ return this.animate({height: "toggle"}, speed, callback);
+ },
+
+ fadeIn: function(speed, callback){
+ return this.animate({opacity: "show"}, speed, callback);
+ },
+
+ fadeOut: function(speed, callback){
+ return this.animate({opacity: "hide"}, speed, callback);
+ },
+
+ fadeTo: function(speed,to,callback){
+ return this.animate({opacity: to}, speed, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var optall = jQuery.speed(speed, easing, callback);
+
+ return this[ optall.queue === false ? "each" : "queue" ](function(){
+ if ( this.nodeType != 1)
+ return false;
+
+ var opt = jQuery.extend({}, optall);
+ var hidden = jQuery(this).is(":hidden"), self = this;
+
+ for ( var p in prop ) {
+ if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
+ return jQuery.isFunction(opt.complete) && opt.complete.apply(this);
+
+ if ( p == "height" || p == "width" ) {
+ // Store display property
+ opt.display = jQuery.css(this, "display");
+
+ // Make sure that nothing sneaks out
+ opt.overflow = this.style.overflow;
+ }
+ }
+
+ if ( opt.overflow != null )
+ this.style.overflow = "hidden";
+
+ opt.curAnim = jQuery.extend({}, prop);
+
+ jQuery.each( prop, function(name, val){
+ var e = new jQuery.fx( self, opt, name );
+
+ if ( /toggle|show|hide/.test(val) )
+ e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+ else {
+ var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
+ start = e.cur(true) || 0;
+
+ if ( parts ) {
+ var end = parseFloat(parts[2]),
+ unit = parts[3] || "px";
+
+ // We need to compute starting value
+ if ( unit != "px" ) {
+ self.style[ name ] = (end || 1) + unit;
+ start = ((end || 1) / e.cur(true)) * start;
+ self.style[ name ] = start + unit;
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] )
+ end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
+
+ e.custom( start, end, unit );
+ } else
+ e.custom( start, val, "" );
+ }
+ });
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ queue: function(type, fn){
+ if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
+ fn = type;
+ type = "fx";
+ }
+
+ if ( !type || (typeof type == "string" && !fn) )
+ return queue( this[0], type );
+
+ return this.each(function(){
+ if ( fn.constructor == Array )
+ queue(this, type, fn);
+ else {
+ queue(this, type).push( fn );
+
+ if ( queue(this, type).length == 1 )
+ fn.apply(this);
+ }
+ });
+ },
+
+ stop: function(clearQueue, gotoEnd){
+ var timers = jQuery.timers;
+
+ if (clearQueue)
+ this.queue([]);
+
+ this.each(function(){
+ // go in reverse order so anything added to the queue during the loop is ignored
+ for ( var i = timers.length - 1; i >= 0; i-- )
+ if ( timers[i].elem == this ) {
+ if (gotoEnd)
+ // force the next step to be the last
+ timers[i](true);
+ timers.splice(i, 1);
+ }
+ });
+
+ // start the next in the queue if the last step wasn't forced
+ if (!gotoEnd)
+ this.dequeue();
+
+ return this;
+ }
+
+});
+
+var queue = function( elem, type, array ) {
+ if ( !elem )
+ return undefined;
+
+ type = type || "fx";
+
+ var q = jQuery.data( elem, type + "queue" );
+
+ if ( !q || array )
+ q = jQuery.data( elem, type + "queue",
+ array ? jQuery.makeArray(array) : [] );
+
+ return q;
+};
+
+jQuery.fn.dequeue = function(type){
+ type = type || "fx";
+
+ return this.each(function(){
+ var q = queue(this, type);
+
+ q.shift();
+
+ if ( q.length )
+ q[0].apply( this );
+ });
+};
+
+jQuery.extend({
+
+ speed: function(speed, easing, fn) {
+ var opt = speed && speed.constructor == Object ? speed : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && easing.constructor != Function && easing
+ };
+
+ opt.duration = (opt.duration && opt.duration.constructor == Number ?
+ opt.duration :
+ { slow: 600, fast: 200 }[opt.duration]) || 400;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function(){
+ if ( opt.queue !== false )
+ jQuery(this).dequeue();
+ if ( jQuery.isFunction( opt.old ) )
+ opt.old.apply( this );
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+ timerId: null,
+
+ fx: function( elem, options, prop ){
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ if ( !options.orig )
+ options.orig = {};
+ }
+
+});
+
+jQuery.fx.prototype = {
+
+ // Simple function for setting a style value
+ update: function(){
+ if ( this.options.step )
+ this.options.step.apply( this.elem, [ this.now, this ] );
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+ // Set display property to block for height/width animations
+ if ( this.prop == "height" || this.prop == "width" )
+ this.elem.style.display = "block";
+ },
+
+ // Get the current size
+ cur: function(force){
+ if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
+ return this.elem[ this.prop ];
+
+ var r = parseFloat(jQuery.css(this.elem, this.prop, force));
+ return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
+ },
+
+ // Start an animation from one number to another
+ custom: function(from, to, unit){
+ this.startTime = (new Date()).getTime();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || "px";
+ this.now = this.start;
+ this.pos = this.state = 0;
+ this.update();
+
+ var self = this;
+ function t(gotoEnd){
+ return self.step(gotoEnd);
+ }
+
+ t.elem = this.elem;
+
+ jQuery.timers.push(t);
+
+ if ( jQuery.timerId == null ) {
+ jQuery.timerId = setInterval(function(){
+ var timers = jQuery.timers;
+
+ for ( var i = 0; i < timers.length; i++ )
+ if ( !timers[i]() )
+ timers.splice(i--, 1);
+
+ if ( !timers.length ) {
+ clearInterval( jQuery.timerId );
+ jQuery.timerId = null;
+ }
+ }, 13);
+ }
+ },
+
+ // Simple 'show' function
+ show: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ this.custom(0, this.cur());
+
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ if ( this.prop == "width" || this.prop == "height" )
+ this.elem.style[this.prop] = "1px";
+
+ // Start by showing the element
+ jQuery(this.elem).show();
+ },
+
+ // Simple 'hide' function
+ hide: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function(gotoEnd){
+ var t = (new Date()).getTime();
+
+ if ( gotoEnd || t > this.options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ this.options.curAnim[ this.prop ] = true;
+
+ var done = true;
+ for ( var i in this.options.curAnim )
+ if ( this.options.curAnim[i] !== true )
+ done = false;
+
+ if ( done ) {
+ if ( this.options.display != null ) {
+ // Reset the overflow
+ this.elem.style.overflow = this.options.overflow;
+
+ // Reset the display
+ this.elem.style.display = this.options.display;
+ if ( jQuery.css(this.elem, "display") == "none" )
+ this.elem.style.display = "block";
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( this.options.hide )
+ this.elem.style.display = "none";
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( this.options.hide || this.options.show )
+ for ( var p in this.options.curAnim )
+ jQuery.attr(this.elem.style, p, this.options.orig[p]);
+ }
+
+ // If a callback was provided, execute it
+ if ( done && jQuery.isFunction( this.options.complete ) )
+ // Execute the complete function
+ this.options.complete.apply( this.elem );
+
+ return false;
+ } else {
+ var n = t - this.startTime;
+ this.state = n / this.options.duration;
+
+ // Perform the easing function, defaults to swing
+ this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
+ this.now = this.start + ((this.end - this.start) * this.pos);
+
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+
+};
+
+jQuery.fx.step = {
+ scrollLeft: function(fx){
+ fx.elem.scrollLeft = fx.now;
+ },
+
+ scrollTop: function(fx){
+ fx.elem.scrollTop = fx.now;
+ },
+
+ opacity: function(fx){
+ jQuery.attr(fx.elem.style, "opacity", fx.now);
+ },
+
+ _default: function(fx){
+ fx.elem.style[ fx.prop ] = fx.now + fx.unit;
+ }
+};
+// The Offset Method
+// Originally By Brandon Aaron, part of the Dimension Plugin
+// http://jquery.com/plugins/project/dimensions
+jQuery.fn.offset = function() {
+ var left = 0, top = 0, elem = this[0], results;
+
+ if ( elem ) with ( jQuery.browser ) {
+ var parent = elem.parentNode,
+ offsetChild = elem,
+ offsetParent = elem.offsetParent,
+ doc = elem.ownerDocument,
+ safari2 = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),
+ fixed = jQuery.css(elem, "position") == "fixed";
+
+ // Use getBoundingClientRect if available
+ if ( elem.getBoundingClientRect ) {
+ var box = elem.getBoundingClientRect();
+
+ // Add the document scroll offsets
+ add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
+ box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
+
+ // IE adds the HTML element's border, by default it is medium which is 2px
+ // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
+ // IE 7 standards mode, the border is always 2px
+ // This border/offset is typically represented by the clientLeft and clientTop properties
+ // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
+ // Therefore this method will be off by 2px in IE while in quirksmode
+ add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
+
+ // Otherwise loop through the offsetParents and parentNodes
+ } else {
+
+ // Initial element offsets
+ add( elem.offsetLeft, elem.offsetTop );
+
+ // Get parent offsets
+ while ( offsetParent ) {
+ // Add offsetParent offsets
+ add( offsetParent.offsetLeft, offsetParent.offsetTop );
+
+ // Mozilla and Safari > 2 does not include the border on offset parents
+ // However Mozilla adds the border for table or table cells
+ if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
+ border( offsetParent );
+
+ // Add the document scroll offsets if position is fixed on any offsetParent
+ if ( !fixed && jQuery.css(offsetParent, "position") == "fixed" )
+ fixed = true;
+
+ // Set offsetChild to previous offsetParent unless it is the body element
+ offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
+ // Get next offsetParent
+ offsetParent = offsetParent.offsetParent;
+ }
+
+ // Get parent scroll offsets
+ while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
+ // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
+ if ( !/^inline|table.*$/i.test(jQuery.css(parent, "display")) )
+ // Subtract parent scroll offsets
+ add( -parent.scrollLeft, -parent.scrollTop );
+
+ // Mozilla does not add the border for a parent that has overflow != visible
+ if ( mozilla && jQuery.css(parent, "overflow") != "visible" )
+ border( parent );
+
+ // Get next parent
+ parent = parent.parentNode;
+ }
+
+ // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
+ // Mozilla doubles body offsets with a non-absolutely positioned offsetChild
+ if ( (safari2 && (fixed || jQuery.css(offsetChild, "position") == "absolute")) ||
+ (mozilla && jQuery.css(offsetChild, "position") != "absolute") )
+ add( -doc.body.offsetLeft, -doc.body.offsetTop );
+
+ // Add the document scroll offsets if position is fixed
+ if ( fixed )
+ add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
+ Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
+ }
+
+ // Return an object with top and left properties
+ results = { top: top, left: left };
+ }
+
+ function border(elem) {
+ add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
+ }
+
+ function add(l, t) {
+ left += parseInt(l) || 0;
+ top += parseInt(t) || 0;
+ }
+
+ return results;
+};
+})();
+jQuery.noConflict();
+/*
+ * XOCom Javascript Source
+ *
+ * This source creates a global XO object that communicates
+ * with the python XPCom code running this activity.
+ *
+ * Your HTML file should register several callbacks with
+ * the XO object to handle requests from the activity:
+ *
+ * Example: A handler for the activity read_file and write_file
+ *
+ * <script type="text/javascript">
+ * XO.register('read', function(content) {
+ * // Your code to consume the supplied content
+ * })
+ * XO.register('write', function() {
+ * // Your code to return the content to save
+ * return 'monkey'
+ * })
+ * </script>
+ *
+ * Some commands for debugging are put in an element with the
+ * id 'xo-status' if it exists.
+ */
+
+var SocialCalc; // All values are stored in the master SocialCalc object
+ if (!SocialCalc) {
+ SocialCalc = {};
+ }
+
+
+var XO = window.XO = {
+ errorMessage: 'everything is fine till now',
+ flagShared:false, //To check that the activity is shared or not, its value will be changed to true by the check string sent by the xocom.py
+ callbacks: { },
+ set_status: function (msg) {
+ jQuery('#xo-status').html(msg)
+ },
+ observer: {
+ setSheet: function(loadstr){
+ XO.callbacks["read"](loadstr);
+ },
+ observe: function(req_obj,topic,command) {
+ now = new Date().getTime();
+ XO.set_status("(" + now + ") Handling " + command);
+ try {
+ // We need access to use the XPCom functions below
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+ req_obj = req_obj.QueryInterface(Components.interfaces.nsIMutableArray);
+ if (req_obj.length){XO.errorMessage=XO.errorMessage+'..........the length of req_obj is 0';}
+ SocialCalc.Constants.s_MainHelpText=SocialCalc.Constants.s_MainHelpText+'got into the observer fn'
+
+ //would be unwrapping the array thing here only if it is not related to the sharing command, else will handle in the called function itself
+ var handle_sharing=false;
+ if (command=='execute')
+ {
+ XO.errorMessage=XO.errorMessage+' \n calling the command from observer';
+ return_value = XO.callbacks[command](req_obj) || '';
+ handle_sharing=true;
+ XO.errorMessage=XO.errorMessage+' \n returned successfully in the observer after the call';
+ }
+
+ if (handle_sharing==false)
+ {
+ // Unwrap the XPCom objects to get at the data passed to us
+
+ var command_arg = undefined
+ if (req_obj.length) {
+ var iter = req_obj.enumerate();
+ xp_arg = iter.getNext();
+ xp_arg = xp_arg.QueryInterface(Components.interfaces.nsISupportsString);
+ command_arg = xp_arg.toString();
+ }
+
+
+ // Execute the registered callback method
+ return_value = XO.callbacks[command](command_arg) || '';
+
+ // Wrap the return value back into the XPCom object
+ var result = Components.classes["@mozilla.org/supports-string;1"].createInstance(
+ Components.interfaces.nsISupportsString);
+ result.data = return_value;
+ req_obj.clear();
+ req_obj.appendElement(result, false);
+ XO.set_status("(" + now + ") Handled " + command + ": (" + return_value + ")");
+ }
+ }
+ //end of if for handle sharing
+
+ catch (err) {
+ XO.errorMessage='here lies the problem'+err;
+ }
+ }
+ },
+
+ observe: function()
+ { a='a';
+ try
+ {
+ //netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect")
+ //req_obj = req_obj.QueryInterface(Components.interfaces.nsIMutableArray)
+ //if (req_obj.length==0){XO.errorMessage=XO.errorMessage+'..........the length of req_obj is 0';}
+
+
+
+ // unwrapping each part of the array and assigning the value to the socialcalc constants
+ //var iter = req_obj.enumerate()
+ for(i=0;i<XO.lang.length;i=i+2)
+ {
+ xp_arg = XO.lang[i]; //iter.getNext()
+ //xp_arg = xp_arg.QueryInterface(Components.interfaces.nsISupportsString)
+ command_arg = xp_arg;//.toString()
+
+ xp_arg2 = XO.lang[i+1]; //iter.getNext()
+ //xp_arg2 = xp_arg2.QueryInterface(Components.interfaces.nsISupportsString)
+ command_arg2 = xp_arg2;//.toString()
+
+ // now assigning the value to the constants
+ SocialCalc.Constants[command_arg]=command_arg2
+ SocialCalc.LocalizeStringList[command_arg]=command_arg2 //LOC_NOTE: this line is just for testing purposes right now... should not be required I believe
+
+ }//endof for
+
+ // returning the result
+ return_value = 'reaching here successfully'
+
+
+ // Wrap the return value back into the XPCom object
+ //var result = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString)
+ //result.data = return_value
+ //req_obj.clear()
+ //req_obj.appendElement(result, false)
+
+ }//end of try
+ catch (err)
+ {
+ XO.errorMessage='here lies the problem'+err;
+ //SocialCalc.Constants.s_MainHelpText=SocialCalc.Constants.s_MainHelpText+'error lies in localize_error on line 3540 of xocom.js '+err
+ }//end of catch
+
+ // returning the result
+ return_value = 'reaching outside atleast'
+
+ // Creating and Displaying the Socialcalc UI
+ // NOTE: It needs to be done only once the constants are all changed in socialcalc.constants
+ spreadsheet.InitializeSpreadsheetControl("tableeditor");
+ spreadsheet.ExecuteCommand('redisplay', '');
+
+
+ // Wrap the return value back into the XPCom object
+ var result = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString)
+ result.data = return_value
+ req_obj.clear()
+ req_obj.appendElement(result, false)
+
+ },
+
+
+
+ register: function(command, callback) {
+ XO.callbacks[command] = callback
+ }
+}
+
+/*
+ * This snippet registers the XO observer to receive commands
+ * from the python XPCom code
+ */
+
+XO.register('check',function(){XO.flagShared=true;}) //changed the value of the shared flag
+
+//SocialCalc.Constants.s_MainHelpText=SocialCalc.Constants.s_MainHelpText+'I am here'
+try {
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+ var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
+ observerService.addObserver(XO.observer, 'xo-message', false);
+ observerService.addObserver(XO.localize_observer, 'xo-message3', false);
+ //SocialCalc.Constants.s_MainHelpText='I am here'
+}
+catch(err) { //NOTE: This part should be removed from here as there is no element named as xo-status, it has been taken from the OnePageWiki portion
+ // Wait a bit to show this error, so the page has time to load up.
+ //SocialCalc.Constants.s_MainHelpText=SocialCalc.Constants.s_MainHelpText+'\nerror lies while setting observer service on line 3563 of xocom.js'+err
+ setTimeout( function() {
+ jQuery('#xo-status', 'JS Error: ' + err);
+ }, 1000)
+}