Name | Description | Documentation | demo | |
---|---|---|---|---|
empiricalPdfs | Create "empirical" (non-parametric) probability distribution functions -- that can be queried for any value.
List of functions
pObj=makeEmpricalPdf(min,max,xRef,probRef) -- create an emprical pdf object
pObjA=changeMeanPdf(pObj,newMean) -- change mean of an empirical pdf, retaining upper and lower bounds
pval=figPdfValue(x,pdfObj) -- marginal probality of x, using pdf defined in pdfObj (x can be any real number)
cumval=figCdfValue(x,pdfObj) -- cumulative probability of x, using pdf defined in pdfObj (x can be any real number)
histoPdf(anid,pobj,height) -- create a histogram of the pdf in the pobj emprical pdf object
newObj=weightedSumPdf(pdfobjs,weights,donorm) -- Create an array of weighted sums of several pdfs: each elment being the weighted sum of corresponding elements in the pdfs
These functions create, and work with, what are called "empircal PDF" objects (pdfObjs). A pdfObj contains
the following fields:
pdf: an array containing "emprical pdf" probability values.
It is defined for every integer between min and max. It's elements will sum to 1.0
min : minimum value (the first defined element of the pdf array) and
max: maximum value (the last defiend element of the pdf array)
mean : mean value from this pdf
cdf: cumulative distribution function corresponding to the points in the pdf (
Note that the the pdf array can contain 0s (for zero probablity) anywhere, epecially at the either tails.
Also, cdf[min]=0 and cdf[max]=1.0
|
documentation | example | |
sortTable |
Read an HTML <table> from a document, and add sort buttons to the header row.
A selected table will be replaced with a sortable version, retaining the attributes/formatting of the original rows and cells.
Each cell can contain any html. However, sorting will occur on two possible values:
The first non-whitespace text element.
If there is an element with a name="_sortUse", the value attribute of it is used.
The "_sortUse" trick allows the sorting to be independent of what is displayed.
Thus:
<td>3 </td>
<td> <span _sortUse="3" />33 </td>
<td> 3 <a href="go3">more</a> </td>
will all sort using a value of "3"
The sort detects whether there are any non-numeric values in the chosen column, and sorts using alphabet order
if there are (otherwise, numeric order is used).
By default, the first row is ALWAYS assumed to be headers, and will NOT be sorted.
In fact, there is an option to place this first row in a non-moving header: you scroll the table contents while the header
stays in the same position.
|
documentation | demo | |
wsAjaxSubmit |
Submit a form via an ajax request, and callback with server response (using <input> and other element values).
List of functions
ws_ajaxFormRequest(athis,acallback,afailCallback,anarg,aDataType,progress,limits) -- set up
ws_ajaxFormRequestOk(aname,data,anarg) -- default callback
ws_ajaxFormRequestFail(aname,ajx,astatus,errt,anarg) -- default callback (when a failure occurs)
Basic useage:
Include in a <form ... >
onSubmit="ws_ajaxFormRequest(this,'callback','failCallback',anarg,dataType);return false";
Be sure to include the "return false " -- it prevents browser from doing a standard submit.
Or for those who think inline events are grossly 1990's (assume the form's name is "myform") :
$('[name="myform"]').on('submit',function(){
event.stopPropagation();
ws_ajaxFormRequest(this,callback,failCallback,anarg,dataType,progressFunction );
});
|
documentation | example | |
wsurvey_bulkEmail |
Implement bulk emailing (broadcasting emails to a number of recipients).
Features:
Enter a text, or html, email.
Both components can be entered seperately, in a standard HTML form <textarea>. Or one can specify just an HTML version, and a text version will be automatically created
A simple HTML editor can be used to enter the HTML code.
Mail merge capabilties -- one can include special {keycodes} that will be replaced by recipient specific values.
You (the administrator) can pre-specify keycodes (such as the current time).
You can provide some, or all, end-users a form to on-the-fly create mail merge values for each recipient.
A simple {keycode} insertion menu is available.
You allow some, or all, endusers to add attachments
End-users sending an email can review it first. They can also:
Preview recipient specific messages -- with mail merge replacements displayed
Edit any of these messages
Select which of the recipients to email the message to (or send an email to all the recipients)
Emails are delivered one at a time. End-users can stop (and resume) the process if desired.
A verification email (a bcc of the email) can be sent to the sender for each recpient (thus, if one emails 4 recipients, 4 seperate verification emails will be emailed to the sender).
Status messages (including SMTP messages) can be displayed
The administrator (who controls the code that uses wsurvey_bulkEmail library) can control which of the above features is available to any given end-user. For example:
Do not display the email address of all, or a subset, of the recipients. That means emails will be sent to these recipients, but their email addresses will not be displayed anywhere.
You can provide preview, or edit, capabilities only to special end users
The ablity to add attachments can be granted only to special end users
HTML code entry can be checked for unsafe HTML -- with potentially dangerous code removed.
Or you can allow some users to send potentially dangerous HTML email.
|
documentation | demo || demo (quick) | |
wsurveyButtonToText |
Click on button(s) to copy/remove value from a list of textboxes.
Useage:
buttonsToText(buttonClass,textClass,bdata)
Typically, there are several buttons and several textboxes (often, there are more buttons than textboxes)
When a button is clicked, its value (or the value of its 'useValue' attribute) is copied to the first "empty" textbox.
If the value is already copied to a textbox, erase it.
Thus, clicking a button will toggle the prescence of its value in the set of textboxes
Typically, <input type="button" ...> are used as buttons, and <input type="text" ... > are used as "textboxes" --
but basically anything can be used as "buttons"; and anything can be used as "textboxes".
|
documentation | demo | |
wsurvey_choser |
Create html code containing a set of checkboxes that allows the end-user to chose values
The enduser can chose zero, one, or more values (by clicking on checkboxes).
Selected values are returned (via a callback) as an array
Functions:
content=wsChoser_create(items,options,myCallback,displayOptions) -- creates content to be displayed
wsChoser_style(atype,prefix,afactor) -- format content using some pre-defined styles
choices=wsChoser_submit(prefix,afunc,arg2) -- return an array of the values of the selected (checkbox checked) choices
|
documentation | demo | |
wsurveyDropdown |
Two methods for creating dropdown menus (single or multiple levels)
astat= ws_dropDownMenu(buttonId,menuId,options) -- single level menus
addDroddownCssRules() -- deep menus
|
documentation | demo | |
wsurveyEquation |
Calculate an equation (specified in a string)
Syntax:
avalue=wsurvey_doEquation(equationString,lookupFunc )
Where:
equationString : a string containing an equation.
lookupFunc : function object.
avalue: will be a numeric value, or a string. Or null if an error occurred.
The equation string can contain values, variable names, operators, and functions.
|
documentation | demo | |
wsurvey_form |
In a new window (or existing container) write a <form> elements -- and then retrieve values.
wsurvey_form can:
a) write the contents of a <form> to this container (or new window)
b) add callback event handlers to "submit" buttons on this form.
c) on click of a "submit", retrieve the fields (<input>, etc) in this <form>
List of functions:
wsForm_setup(content,windowOptions,saveOptions) :: write content to new window,
wsForm_forceClose(gVarnamne) :: close a window created by wsForm_setup
wsForm_forceSubmit(gVarnamne) :: get current values specified in a new window
wsForm_info(gVarname) :: create table of information from this form
|
documentation | demo | |
wsurveyMoveBox | Create moveable and resizable boxes.
Syntax:
setupMoveBox(boxid,moveid,resizeid,closeid,acomment) -- boxid element becomes a moveable box
createMyMoveBox(boxid,opts) { -- boxid element becomes a moveable box (fewer options)
One creates an element (such as a DIV) which we call the "moveable box".
One then adds sub elements (such as SPANs) that will be treated as small buttons.
These small buttons can be used to move, resize, or hide the element; with moving and resizing by clicking
and dragging the appropriate button
For simplicity sake, these small buttons can be automatically created for you.
|
generic || showAlertOntop | setupMoveBox || createMyMoveBox | |
wsurvey_readFiles |
Simplify file uploads using <input type="file" ...>
These functions are designed to make the contents of a file upload accessible to javascript functions.
Important useage: when using ajax to transfer information to a php script; you can use these functions
to explicitily access the contents of a file upload.
Function list
uploadInfo=ws_readFiles_setup(useid,options) -- initial setup.
ws_readFiles_clear(uploadInfo) -- reset & clear file upload elements
ws_readFiles(evt) -- event manager assigned to <nput type="file"> element.
ws_readFiles_unpack(storeName) -- unpack information stored by ws_readFiles
|
documentation | demo | |
wsurveyResizer |
Resize horizontal and vertical sizes of adjacent containers.
Syntax:
resizer_init(blocka,blockb,mover,dire,minsize,dormb)
Examples:
resizer_init('mainBlock_1a mainBlock_1b','mainBlock_2','mainBlock_rowSep','V',50,1);
resizer_init('mainBlock_1a','mainBlock_1b','mainBlock_colSep','H',50,[40,70]);
resizer_init('mainBlock_1a','mainBlock_1b','mainBlock_colSep','H',50,[70,90,10,30,50]);
|
documentation | simple || resizable | |
wsurveyShowAlert |
Functions to show alerts in a moveable popup containers; and to show status messages in popup containers.
Summary of functions:
init_showStuff(maxmove) -- intialize containers, and click handlers used by showAlertOnTop and showStatusMessage
showStatusMessage(amess,aduration,dohold,boxnum) -- display a message in a status box
showAlertOnTop(amess,aopts,doAppend,dofade,cancelFade,dofunc) -- display a message in an "alert box"
hideAlertOnTop() -- hide an alert box
minimizeAlertOnTop(aid) -- minimize alert box
maximizeAlertOnTop(this) -- maximize alert box
showAlertBoxMoveStart(evt) -- handler used to enable move & resize of alert box
showAlertMessageInNewWindow(aid,atitle) -- copy contents of alert box to a new browser window
showMessageHistory(viewName) -- open new window with list of messages written
showAlertOnTop_doEsc(evt,akey) -- enable ESC key (to close showAlertOnTop box
showStatusMessage(amess,aduration,dohold,boxnum) -- display a message in a status box
showStatusMessage2(amess,aduration,dohold,boxnum) -- display a message in a status box
|
documentation | demo | |
wsurveyUtils1 | General functions for working with html documents (used by many other libraries).
Function list:
abortJavaScript(amess,showtrace) -- display a message and clumsily exit javascript
addComma(nStr) -- add commas to a number (13612.5 becomes 13,612.6)
addCssRule(cid,rules) -- add a style sheet, or add rule to an existing style sheet
base64 ...
base64_encode(data) -- base64 encoder (not binary safe)
Base64.encode -- synonym for base64_encode
$.base64('encode',astring) -- base64 encoder
base64_decode(data) -- base64 decoder
Base64.decode -- synonym for base64_decode
$.base64('decode',astring) -- base64 dencoder
bin2hex(s) -- binary to hex
classShow(selectorText) -- unhide a css rule (in the global style sheet)
$.checkTags=function(text,ignore) -- check a string containing html for tag errors (unclosed tags)
crc32 (str) -- crc32 of a string
cssClassExists(aclass0) -- looks in all active style sheets for a .class definition
dechex(anumber) -- decimal to hex converter (10 becomes a, 47 becomes 2f)
displayStringInWindow(stuff,cvt,astext,aheader,winname,yesbars,awidth0,aheight0) -- display string in a new HTML window
displayElsewhere(aid,atitle,stuff3) -- display contents of id="aid" element, or stuff3, in new window
dump(v, howDisplay, recursionLevel) -- display fields of an object (like php var_dump)
dump_repeatString(str, num) -- returns a string which has been repeated a set number of times
echoFileBack(contents,atarget,atype,afilename) -- echo a string back as a file, using a POST. Works with the echoFileBack.php
getWord(astring,nth,adelim) -- return array list of words, or the nth word
get_currentTime(timeType,dateType) -- return time and/or date
getJqueryObjects(a1s0,amess,just1) -- return jQuery objects
hex2bin(hex) -- hex to bineary
html tag conversion ...
htmlTagsConvert(str) -- html tags to entties (<b> becomes <b> )
htmlspecialchars(str) -- synonym for htmlTagsConvert
htmlEntities(str) -- similar to htmlTagsConvert
escapeHtml(text) -- similar to htmlTagsConvert
someHTMLEncode(str) -- html encode a string for a limited set of characters (more powerful thatn htmlTagsConvert)
htmlEntitiesReverse(str) -- convert html entities (i.e. < becomes <)
unescapeHtml(text) -- similar to htmlEntitiesReverse
someHTMLDecode(str,others,justOthers) -- decode limited set of html enties in string: that have a syntax of nn;
makeHtmlSafe(atext) -- remove most attiributes (such as onClick, etc), and hazardous tags, from string
nl2br(str, is_xhtml) -- convert sequences of crlfs to a <br>
parseAt(theString,achar) -- split string into two parts, using achar
parseUsing(thevar,d1,d2,allp ) -- split string into three parts, using d1 and d2 characters
removeMostAttributes(q1,whitelist,blacklist) -- remove attributes from elements in jquery object
rot13(astr) -- rot13 string converter (for weak obsfucation)
Seconds_ToTime(towait,maxhrs) -- convert a number of seconds to hh:mm:ss format
show_dollars(avalue) -- convert a number to $mm.cc
styleToJquery(astyle) -- convert a style="s1:value;s2:value" type of string to an object useable by $().css()
scorePassword1(pass) -- score the quality of a password
scorePassword2(strPassword, strFieldID) -- score the quality of a password, and display graphic
strip_active_tags(hcontent) -- remove action tags (script, style, head) from string of html content.
trim(str,which) -- trim spaces (similar to jQuery.trim()
updateOptionsObject(vals,newVals,checkType,okFields,synonyms) -- update fields in an vals object, using fields in newVals object
utf8_encode (argString) -- ISO-8859-1 string to utf-8
wrapLongLines(aid) -- wrap wrap long lines in an element with id of aid
wsBase64_encode(astring) -- general purpose base64 encoder; tries to handles both utf-8 and binary (but stupidly
ws_object_toArray64(aval,fieldlist,buildon) -- convert open ended multi depth object (or array) to flat array
ws_obsfucate(astring) -- somewhat strong string obsfucation
ws_unobsfucate(astring) -- unobsfucate output of ws_obsfucate
|
documentation | demo | |
wsurveyUtilsDom | DOM manipulation functions. This is used by several of the other more elaborate libraries.
List of functions (arguments omitted).
attlist = myNode.getAllAttributes(showme) : Return all attributes of an element
copyAllAttributes(fromNode,toNode,skipattribs) : copy attributes from fromNode to toNode (with optional skips)
aval = get_elemValue(e1Look,defval,modifiers,flagVar) : Read an elements "value".
aval = get_elemNumber(anelem,defval,opts) : Read element's value as a number
vlist = getJqueryObjects(a1s0,amess,just1) : return array of jQuery objects
tstrg = getNodeText(cget,dropempty,whichText,dotrim) : Extract text nodes, return as a string (get_NoteText and get_nodeText are synonyms)
atrVal = readAttribute(aid,attlist,adef,noTrim) : Read attributes of an element
attrValue = readAttributeNode(anode,attlist,adef,noTrim,asObj) : Pull attribute out of element
avalue = read_node_attribute(anode,nodename,attname,adefault,doremove,gVar) : Pull value from an attribute or a child node
atree = replicateTreeWithUpdate(aid,igroup,oldDis,newDis,grpAt,useAtt,shwGrp,modId) :: replicate a tree, with updating of attributes
astat = set_elemValue(e1,useval,flagvar) : Set an element's value
updateBlocks(htmlString,oldIds,newIds,actions0) : update content on page using content in a string of html (or xml)
|
documentation | ... | |
wsurveyUtils2 | General functions for working with html documents (complements wsurveyUtils1)
List of functions:
checkRadiosDone(fname,alist,aprompt) :: verify that one of a set of radio buttons was selected
clickOnPriorSibling(athis,checkVisible) :: / click on the prior sibling of athis
doButtonToggler(evt,opt1,opt2,opt3) :: toggle view of help boxes
isHTMLElement(obj) :: detects html element (isHTMLelement is a synonym)
makeATable(alist,ncols2,astyle1,athrow,tablespec) :: given a list, create an html table as a string
showKeyword(dakey,keyWordSearch,enclosure,hdrRow,hdrClass) :: toggle display of one of a set of "description" boxes (all other boxes in the set will be hidden)
submitQuickForm(action, method, input,target) :: submit data to a form, using either post or ge
toggleView(ids,mess1,mess2,idswitch) :: toggle viewing a set of elements using a single "switch" element (such as a button or a link)
toggleView2(id1,id2,mess1,mess2,idswitch) :: toggle view between id1 and id2 elements, and change message in switch element between mess1 and mess2
turnDisplayOn(a1s0,doit,amess ) :: display or hide an element
|
documentation | demo | ... |
wsurveyUtilsEvents | Create countdown timers and ajax queries (used with wsurveyWatches.js)
The initialization function (ws_initEvents) will look for, and appropriately process, elements in the
body of the document with the following tags:
<query>
Retrieve a value using an AJAX call to a server (i.e.; to the defaultQuery)
This value is stored in a global "query" database, where it can be retrieved at
any later time by any other javascript function.
In addition, a custom function may be called on success, that can use this
retrieved value as needed.
<timer>
Start a timer, and call a function when it expires.
A countdown of seconds remaining can be displayed.
|
documentation | demo | |
wsurvey_userData | Allow end-user to modify one or more variables in a userData table.
Each row of this userData table is an "entry". Each of these entries can have one or move "variables".
Results are saved to an associative array
Functions:
myUserData=wsUserdata_init(options) : initialize the data structure
myUserData=wsUserdata_modify(myUserData,internalNames,externalNames,data) : add or modify variables
status=wsUserdata_add(myUserData) : add, or modify, a variable
status=wsUserdata_extract(myUserData) : extract selected rows and variables
|
documentation | demo | |
wsurveyUtilsWatches |
Set up a "watch" architecture using simple attributes in existing html tags (to support dynamic content).
The functions presented here allow one to set up a complex "watch" architecture using simple
attributes in existing html tags.
Elements can "watch" other elements.
If any one of these "watched" elements changes (and this could be the contents of <span>, or the
value of an <input>), then an element-specific list of functions is called.
Thus, consider some element X (say, an <input>) and elements Y1 and Y2 whose value depends on the
current value of X
One could have onchange events associated with X that update Y1 and Y2.
Instead, this "watch" facility tells Y1 and Y2 to "watch for changes on X", and if a change in X occurs --
update your value.
And this is recursive: elements that are updated because an element they "watch" has changed can result in other elements
(that watch the updated element) also being updated.
IOW: the responsiblity for updating is assigned to the element to be updated,
rather than the elements that might change.
This makes it easier to add and modify elements, and you don't have to be as careful
specifying change and click events!
|
documentation | demo | |
wsurveyXhtml |
Convert special tags to <input> elements -- such as radio buttons, and fancy numeric entry.
xhtml tags supported (sorted by order of processing)
* `include` : insert contents from the server
* `getData` : retrieve "dynamic" variables from the server
* `replicate` : replicate a block of html code several times
* `attributes` : assign attributes to xhtml (and other) elements
* `lookups` : lookup and use dynamic variables to
* `if` : selectively include content
* `number` : input a number
* `text` : input some text
* `radios and radio` : specify a set of radio buttons
* `checkbox` : specify a check box
* `show` : show the value of a dynamic variable
* `help` : create button(s) to view one of a set of help messages
* `more` : create a button to display more information
* `ajax` : submit form using ajax (with callback)
* `loadPages` : retrieve a local cache of html pages
* `events` : wait for events and do actions when they occur
|
documentation | list of demos | |
wsurveyXMLattribute |
Parse a XML file, and use to set element attributes in the html document.
The XML file used by xmlToAttributes should specify what attributes (and their values)
to assign to what elements of the html document.
The first level children (the "main children") of the mainNode are the basic "instructions",
with the tagname used as identifiers.
Grandchildren (children of these "main children instructions") provide details; they are
used to specify attribute names & values, or to identify which elements to modify.
All other levels (i.e.; third generation nodes) are ignored.
The tagname of the main children identifies which elements to modify, or which attributes to modify.
A type attribute should be included, that determines what is matched:
type="id" : modify attributes of element with this id
type="name" : modify attributes of all elements with this name
(same values of the attributes assigned to each of these elements)
type="class" : modify attributes of all elements with this class
(same values of the attributes assigned to each of these elements)
type="tag" : modify attributes of all elements with this tagname
type="attribute" : assign this attribute value to all elements that match
|
documentation | ||
PHP libraries | ||||
divTable |
Functions for making "html tables" from data contained in a multi-dimensional array: a simple csv style table,
and a complex sortabe/markable table.
makeDivTable :
Extensive use of <div> elements. A primary feature is a frozen header line,
with content rows scrollable underneath these headers.
A number of dynamic options are available, including sorting on a column, and
removing and widening columns.
A number of formatting options are available, including cell-specific scroll bars, autosizing column widths,
and truncting long content
makeCSVTable :
Creates comma seperated value table. Padding to align columns is supported.
|
documentation | demo | |
wsPhpLib |
A variety of useful php functions
wsPhpLib functions:
array_size_bytes :: return size, in characters, of an array
arrayToTable :: display each row of an array in a multi-column HTML table
checkSyntaxXML :: check xml syntax of a string.
clear_duplicate_cookies :: clears out the duplicate session cookies
connectDatabase :: connect to a mysql database
consolidateData :: consolidate data (from M rows to 1) from a wsurvey consolidated database
consolidateData2 :: alternate version of consolidateData
consolidateDataByTicket :: multiple tickets version of consolidateData
copy_table :: copy mysql table to a new table (in same mysql database)
custom_number_format :: convert a nunber to k,m
database_exists :: ee if a database exists
do_dump :: show contents of an array, object, etc
extractLatest :: extract "latest" rows from wsurvey consoliddated database
extractCols :: extract columns from an array-of-arrays
extract1Cols :: extract 1 column from an array of arrays
extractRequestVar :: extract request variable
extractRequestVars :: extract request variables whose case-insensitve name starts with a string
findInTree :: find file in a directory tree
findSSI :: find all <? $varname pre> substrings in $string
formatMilliseconds :: convert milliseconds to hh:mm:ss.xxx
getConsolidateInfo :: get parameters from a wsurvey consoliddated database
getWords :: retrieve words in a string
htmlEnclose :: surround a string with an html tag
isValidEmail :: validate an email address
makeShortName :: extract "short name"
makeQQTable :: make a table with response from a mysqli_query
makeArrayTable :: make an html table with values of an array, where each row is an associative array
makeArrayTableFamily :: family version of makeArrayTable
movePage :: redirect utility
nthValue :: convert number to 'nth'
printPre :: print content between <pre> ... </pre>
qqCheck :: check return from ws_mysqli_query
qqToArray :: create an associate array from ws_mysqli_query return
removeCols :: remove columns from an array-of-arrays
replaceShortcuts :: global string replacements of shortcuts
table_exists :: check for $tablename in $database
transposeArray :: transpose an array:
mysqlToCSV :: write a mysql table as a CSV file
mysqlToCSVstring :: write a mysql table as a CSV (return as string)
parseMimeContent :: parse a set of headers
removeDir :: remove a directory tree
restoreMysqlDatabase :: restore mysql database from output file created by saveMysqlDatabase
saveMysqlDatabase :: archive (backup) a mysql database
secondsToDays( :: format seconds to a dd hh:mm or dd.ee format
strip_html_activeTags :: remove HTML tags
toByteSize :: converts xxMb or xxM etc to bytes
ws_obsfucate :: simple string obsfucator
ws_unobsfucate :: simple string unobsfucator
ws_array64_toObject :: recursively add components to an existing array
ws_mysqlCopyRow :: insert a new row in a mysql table
ws_mysqlReplaceRow :: replace" shortcut to ws_mysqlCopyRow
ws_mysqlDelete :: delete a row from a table, and copy to the deletedbox table
ws_readFiles_unpack :: unpack file upload stuff created by ws_readFiles
ws_mysqli_query :: wsurvey "combined" mysqli_query
|
documentation | ||
wsEMailLib_1 |
Standalone send email function -- uses swift email package
First call:
loadSwiftMailer($i)
and then
ws_sendAnEmail($smtpInfo,$sendTos,$sendfrom,$subject,$message,$attachments,$opts,$replacements)
|
documentation | ||
vuDir | View contents of a directory. |
The libraries and applications available here are free software: you can redistribute them and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
These libraries and applications are distributed in the hope that they will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
For a longer version of the GPL license see http://www.gnu.org/licenses/